2012-01-28 3 views
1

私のCSクラスのScheme(R5RS)で式を取る手順を記述しようとしています)を引数とし、(1)式にcarとcdrを使って形成できるすべての式と、(2)元式のこれらの各要素がどのように得られたかを示す式のリストを返します。作品が複数の方法で取得できる場合は、複数回返される必要があります。スキーム:carとcdrの任意の組み合わせを使用して取得できる式のすべての要素を返します。

Examples 

(pieces '()) => ((() x)) 

(pieces 'apple) => ((apple x)) 

(pieces '(apple)) => (((apple) x) (apple (car x)) (() (cdr x))) 

(pieces '(a (b c))) => 
       (((a (b c)) x) 
       (a (car x)) 
       (((b c)) (cdr x)) 
       ((b c) (car (cdr x))) 
       (b (car (car (cdr x)))) 
       ((c) (cdr (car (cdr x)))) 
       (c (car (cdr (car (cdr x))))) 
       (() (cdr (cdr (car (cdr x))))) 
       (() (cdr (cdr x)))) 

私たちはSchemeを使い始めたばかりですから、この割り当てのためのかなり基本的な構文に制限されています。ここで私がこれまで持っているものです。

(define pieces 
    (lambda (exp) 
    (cond 
     ((symbol? exp) 
     (list exp 'x)) 
     ((null? exp) 
     (list '() 'x)) 
     ((list? exp) 
     (let ((b (pieces (car exp))) (c (pieces (cdr exp)))) 
      (list exp 'x b c)))))) 

(pieces '()) => (() x) 

(pieces 'apple) => (apple x) 

(pieces '(apple)) => ((apple) x (apple x) (() x)) 

(pieces '(a (b c))) => ((a (b c)) x (a x) (((b c)) x ((b c) x (b x) ((c) x (c x) (() x))) 
         (() x))) 

手順は、適切なすべての要素を返しますが、それぞれの再帰は、コンポーネントが追加リストにネストされます。それを防ぐ方法はありますか?

また、問題の2番目の部分(それぞれの要素がcarとcdrを使用して元のファイルからどのように取得されたかを示す)をどこから開始するのかはわかりません。何百万ものアプローチを試みてきましたが、どれも近づいていませんでした。誰かがその機能を実装する方法に関するヒントや提案があれば、本当に感謝しています。ありがとう、トン。

+0

すべての原子要素(車やcdrsのチェーンでアクセス可能なもの)が必要なように聞こえるので、* flattenあなたが探している結果を与える。 –

答えて

1
(pieces 'apple) => (apple x) 

しかし、それは((apple x))でしょうか?最初の唯一の要素がリスト(apple x)であるリストを取得する必要があります。

再帰を終了するcond句(expはシンボルまたはnull)は、リストに入る項目を返しますが、carおよびcdrで繰り返される句は項目のリストを作成しようとします。 piecesはアイテムとアイテムのリストの両方を返すことができるので、返される値の中から項目のリストを作成するのは難しいです。(list exp 'x b c)を実行すると、bcがリストまたはアイテムのリスト。

piecesが常にアイテムのリスト(たとえば(list (list exp 'x)))を返すようにすると、それはずっと簡単になります。 carcdrを繰り返すときはappendリストabのようにして、そのリストに「現在」((list exp 'x))の項目を追加してください(おそらくconsなど)。

piecesは、現在のアイテムにどのようになっているかを知っている必要があります。 piecesは現在の項目に(おそらくオプションの)パラメータとして「パス」を取らせることができます。パスがリストの場合、(car exp)piecesを呼び出すと、引数として送信するパスにcarシンボルを追加できます。(cdr exp)には、シンボルcdrを追加できます。そして、パスを使用して'xの代わりに(list exp 'x)を置き換えてください。

0

私はそれがSchemeではないことを知っていますが、おそらく同様の言語を見てみると助かります。私は自分自身を練習するので、塩の点滴とそれを取るために、この多くをやった、まだそれはあなたが後にしているかを正確にやっているように見える:

そして、この出力を生成
(defun parse-list (whatever) 
    (labels ((pieces (expression &optional path) 
     (cond 
      ((null expression) 
     `((,path . nil))) 
      ((listp expression) 
     (append (list 
      `(,path . ,expression)) 
      (pieces (car expression) 
       (cons 'car path)) 
      (pieces (cdr expression) 
       (cons 'cdr path)))) 
      (t `((,path . ,expression)))))) 
    (dolist (output (pieces whatever)) 
     (format t "path ~a => result ~a~&" 
      (car output) (cdr output))))) 

(parse-list '(a (b c))) 

path NIL => result (A (B C)) 
path (CAR) => result A 
path (CDR) => result ((B C)) 
path (CAR CDR) => result (B C) 
path (CAR CAR CDR) => result B 
path (CDR CAR CDR) => result (C) 
path (CAR CDR CAR CDR) => result C 
path (CDR CDR CAR CDR) => result NIL 
path (CDR CDR) => result NIL 

申し訳ありませんが、これよりも書式設定されたSOのコードを取得できませんでした。

+0

実際にそこに 'result'パラメータが必要ないことに注意してください。 'pieces'を呼び出すときに' result'として常に 'nil'を渡しています。 – Jonas

関連する問題