0

我正在尝试学习一些 Common Lisp。我习惯于使用大括号命令式语言,但仍然难以理解 Lisp 风格的思维和语法。

下面是我正在尝试编写的排列函数。它目前已损坏。

如果我用

(permutations '(1 2 3))

我可以在标记为“and here”的断点处看到,此时正在生成诸如 (2 3)、(3 2)、(1 3) 之类的列表。但是通过在 SLIME 中运行跟踪,我看到排列函数在调用之后返回 (2)、(3) 和 (1)(lisp 中的第一项)。然后顶级函数只返回 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. 更改docollect,您将走得更远。

于 2013-09-14T20:11:52.030 回答