我编写了函数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
函数调用次数限制为一个?
答案 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)))