0

私は持っている

(setq l2 '(1 (2 b (c 1 b))(a (1 2) d))) 

(defun drumuri (l3) 
  (cond ((atom l3) (cons l3 nil))
     (t (append
           (cons (car l3) nil)
           (drumuri (cadr l3))
           (cons (car l3) nil)
           (drumuri (caddr l3))))))

(drumuri l2)

そしてそれは私に与えます:

 Break 2 
[4]>     DRUMURI
 Break 2 
[4]>     (1 2 B 2 C 1 C B 1 A 1 2 1 NIL A D)

しかし、私は必要です:

((1 2 B)(1 2 C 1)(1 2 C B)(1 A 1 2)(1 A D)) 

わかりました良いニュース私はいくつかの答えを見つけました:

(setq l2 '(1 (2 b (c 1 b))(a (1 2) d)))
( defun drumuri (l3) 
( cond ( (atom l3) ( cons l3 nil))
       (t (append  ( cons ( car l3 ) nil)
          (drumuri ( cadr l3) )))))
          (drumuri l2)

それに対する答えは次のとおりです。

[1]> 
(1 (2 B (C 1 B)) (A (1 2) D))
[2]> 
DRUMURI
[3]> 
(1 2 B)

次は2番目の答えです。

(defun drumuri (l4) 
    (cond ((atom l4)(cons l4 nil))
    ( t   ( append  (cons ( car l4)nil)
        (drumuri ( caddr l4))))))
            (drumuri l2)

それに対する答えは次のとおりです。

[1]> 
(1 (2 B (C 1 B)) (A (1 2) D))
[2]> 
DRUMURI
[3]> 
(1 A D)

したがって、あとは次を見つけるだけです。

(1 2 C 1) (1 2 CB) (1 A 1 2)

4

1 に答える 1

1

トリッキーな問題。特に複雑ではありませんが、いくつかの厄介なエッジがあります。これは明らかに宿題なので、私はあなたを助けようとしますが、同時にスプーンで食べさせるだけは避けてください (そして、これらの目標の 1 つまたは両方で失敗する可能性があります)。だから私はPythonでそれを書いた。願わくば、これが Lisp から十分に離れていることを願っています。そのためには、まだ自分でよく考えてみる必要があります。

>>> import operator
>>> def drumuri(a):
...     if isinstance(a, list):
...         return reduce(operator.add,
...                       [[a[:1] + d for d in drumuri(x)] for x in a[1:]])
...     else:
...         return [[a]]
... 
>>> drumuri( [1, [2, 'b', ['c', 1, 'b']], ['a', [1, 2], 'd']] )
[[1, 2, 'b'], [1, 2, 'c', 1], [1, 2, 'c', 'b'], [1, 'a', 1, 2], [1, 'a', 'd']]
>>> 

Lisp バージョンに欠けている重要な洞察を次に示します。ドラムリは再帰的であるため、すべてのレベルが同じ種類の構造体を呼び出し元に返さなければなりません: パスのリストで、各パスはリストです。つまり、drumuri は常にリストのリストを返さなければなりません。リーフケースは、単一のアトムを含むリストを返します。

の使用でもいくつかの間違いを犯していますappendが、葉の問題はおそらく他のすべての形状を曲げています。

編集: 自分で解決策を見つけるのに役立つかどうか見てみましょう. 次の手順を実行します:

  1. prepend-to-paths単一のヘッドとパスのリストを取り、元の各パスの先頭にヘッドを追加したパスのリストを返す関数を作成します。次のように動作するはずです。

    > (prepend-to-paths 1 '((2 B) (2 C 1) (2 C B) (A 1 2) (A D))) ;'
    ((1 2 B) (1 2 C 1) (1 2 C B) (1 A 1 2) (1 A D))
    
  2. convert-to-paths未処理の末尾要素のリストを受け取り、それらをパスに変換するという関数を作成します。ただし、すべての作業自体を行うのではなく、入力をパスのリストにマッピングし (drumuri各要素をマッピングするためにまだ書かれていないものに依存する)、返されたパスのリストを単一のパスのリストに連結することだけを考慮する必要があります。 . 出力(drumuri存在する場合)は次のようになります。

    > (convert-to-paths '((2 b (c 1 b)) (a (1 2) d))) ;'
    ((2 B) (2 C 1) (2 C B) (A 1 2) (A D))
    
  3. 関数を書きdrumuriます。元のとおりに使用する必要がありcondますが、葉のケースをパスのリストとしてアトムを返す式に置き換えます。

    > (drumuri 'b) ;'
    ((b))
    

    (append ...)次に、前の手順で記述した関数を使用して入力リスト入力の先頭と末尾をパスのリストに変換するコードに置き換えます。

  4. 3 つの関数がうまく機能するようになったら、最初の 2 つの関数を の本体に折り畳む方法を考えてみましょうdrumuri。この最終結果は、私が提供した Python ソリューションとは構造的に異なる可能性があることに注意してください。

行き詰まった場合は、質問を更新して、これまでに行った進捗状況と、なんとかまとめたコードで更新してください。

于 2010-05-15T09:12:43.997 に答える