在Common Lisp中合并两个列表

时间:2018-11-20 22:51:14

标签: lisp common-lisp

我将自己设置为编写Common Lisp函数的任务,该函数可在不使用append的情况下连接两个列表。

Lisp公用输入(concat-lists '(1 2 3) '(4 5 6))应该返回(1 2 3 4 5 6)

即使我的解决方案似乎可行,它看起来也很复杂

(defun concat-lists(seq1 seq2)
    (cond ((not (null seq1)) (cons (car seq1) (concat-lists (cdr seq1) seq2)))
          (T (cond ((not (null seq2)) (cons (car seq2) (concat-lists seq1 (cdr seq2))))
                   (T nil)))))

我正在寻找一种使用reduce的更优雅的解决方案,其中我使用seq1作为初始值,然后将函数应用于seq2的每个元素,从而附加每个值列表中的seq1。尝试时总会卡住我...

任何帮助或输入,我们将不胜感激。谢谢!

3 个答案:

答案 0 :(得分:4)

CL-USER 39 > (reduce #'cons
                     '(1 2 3 4 5)
                     :initial-value '(a b c d e)
                     :from-end t) 
(1 2 3 4 5 A B C D E)

答案 1 :(得分:4)

Rainer Joswig的解决方案非常优雅,简单,并且尊重您使用reduce的要求。

如果您还希望看到一种递归的简单解决方案,那么这里是经典的解决方案:

(defun concat-lists (seq1 seq2)
  (if (null seq1)
      seq2
      (cons (car seq1) (concat-lists (cdr seq1) seq2))))

(concat-lists '(1 2 3) '(4 5 6))
(1 2 3 4 5 6)

答案 2 :(得分:2)

我确实了解您对“减少”的要求。还有其他选项:

CL也有'concatenante'

(concatenate 'list '(1 2 3) '(4 5 6))

还有另一个不太复杂的(IMHO),并不那么优雅。

(defun concat-lists (list1 list2) (let ((a (copy-list list1)) (b (copy-list list2))) (rplacd (last a) b) a))

(defun concat-lists (list1 list2) (let ((a (copy-list list1)) (b (copy-list list2))) (nconc a b)))