是否可以限制duplicate()函数中cons函数的调用次数?

时间:2017-03-10 14:04:59

标签: list duplicates lisp common-lisp cons

我编写了函数double(),它复制了列表中的项目,如下所示:

(defun duplicate (l)
    (if (null l) nil
        (cons (car l) (cons (car l) ( duplicate (cdr l))))))

duplicate()函数为列表中的每个项目调用CONS函数两次:

Break 1 [2]> (trace cons)
;; Traçage de la fonction CONS.
(CONS)

Break 1 [2]> ( duplicate '(1 2 3))
1. Trace: (CONS '3 'NIL)
1. Trace: CONS ==> (3)
1. Trace: (CONS '3 '(3))
1. Trace: CONS ==> (3 3)
1. Trace: (CONS '2 '(3 3))
1. Trace: CONS ==> (2 3 3)
1. Trace: (CONS '2 '(2 3 3))
1. Trace: CONS ==> (2 2 3 3)
1. Trace: (CONS '1 '(2 2 3 3))
1. Trace: CONS ==> (1 2 2 3 3)
1. Trace: (CONS '1 '(1 2 2 3 3))
1. Trace: CONS ==> (1 1 2 2 3 3)
(1 1 2 2 3 3)

是否可以将每个列表项的CONS函数调用次数限制为一个?

3 个答案:

答案 0 :(得分:1)

不,出于同样的原因,你不能用5升水装满10升水桶。

10个元素的列表需要10个cons单元格。

答案 1 :(得分:0)

破坏性版本可以实现这一目标:

(defun duplicate (l)
  (if (null l)
      nil
    (destructuring-bind (f . r)
        l
      (setf (cdr l)
            (cons f (duplicate r)))
      l)))

CL-USER 10 > (duplicate (list 1 2 3 4 5))
(1 1 2 2 3 3 4 4 5 5)

答案 2 :(得分:0)

你可以消除所有的电话:

(list* (car l) (car l) (duplicate (cdr l)))