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

Is it possible to limit the number of calls to the cons function in the duplicate() function?

我编写了函数 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 函数的调用次数限制为每个列表项一次?

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

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

破坏性版本将使这成为可能:

(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)

你可以消除所有的 cons 调用:

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