0

Common Lisp を手に入れようとしています。私は中括弧の命令型言語に慣れており、Lisp スタイルの考え方と構文に頭を悩ませています。

以下は、私が書こうとしている順列関数です。現在壊れています。

この関数を実行すると

(permutations '(1 2 3))

「and here」というラベルの付いたブレークポイントで、(2 3)、(3 2)、(1 3) などのリストがその時点で生成されていることがわかります。しかし、SLIME でトレースを実行すると、その呼び出し (lisp の最初の項目) の後に順列関数が (2)、(3)、および (1) を返していることがわかります。トップレベルの関数は nil を返すだけです (これもわかりません)。

(defun permutations (coll)
(if (= 1 (length coll))
 (print (list (first coll)))
  (loop for el in coll do
   (map 'list #'(lambda (combos) 
          (if 
               (break "you got here with arguments ~:S." (listp combos))
               (cons el combos)
               (break "and here: ~:S " (list el combos))))

    (permutations (remove el coll))
    ))))

ここで何が間違っていますか?助けてくれてありがとう。

編集:これは、jlahd のコメントに応じて関数を変更した後のものです。これは (((1 ((2 3))) (1 ((3 2)))) ((2 ((1 3))) (2 ((3 1)))) ((3 ((1 2) ))) (3 ((2 1))))) 元の例で呼び出された場合。ネストされたリストの問題を修正する方法はまだわかりません。

(defun permutations (coll)
  (if (= 1 (length coll))
      (print (list (first coll)))
      (loop for el in coll collect
           (map 'list #'(lambda (combos) 
                          (list el combos))    
                (permutations (remove el coll))
                ))))

編集:わかりました、ここで助けてくれてありがとう!これは、Rörd と wxvxw のコメントの後に私が持っているものです。これは実行され、((1 2 . 3) (1 3 . 2) (2 1 . 3) (2 3 . 1) (3 1 . 2) (3 2 . 1)) を返します。ここでの「ドット ペア」表記が単純なリストと比較して何を意味するのか正確にはわかりませんが、それ以外の場合はこれで問題ないようです。

(defun permutations (coll)
  (if (not (cdr coll))
      (list (first coll))
      (loop for el in coll nconc
           (mapcar #'(lambda (combos) 
                       (cons el combos))    
                   (permutations (remove el coll))
                   ))))
4

1 に答える 1

2

で収集したすべてのデータを破棄していますloop。に変更doするcollectと、はるかに遠くなります。

于 2013-09-14T20:11:52.030 に答える