我如何通过嵌套列表进行递归?
例如,给定:'((A 1 2) (B 3 4))
如何将2添加到每个嵌套子列表中的第二个元素?
(defun get-p0 (points)
(loop for x from 0 to
(- (list-length points) 1) do
(+ 2 (cadr (nth x points)))
)
)
我不确定为什么(get-p0 '((A 1 2) (B 3 4)))
会返回NIL。
答案 0 :(得分:3)
我会选择这样的事情:
(loop for (letter x y) in '((A 1 2) (B 3 4))
collect (list letter (+ 2 x) y))
原因:它更短,你不测量列表的长度以便迭代它(为什么你会这样做?)
答案 1 :(得分:2)
因为你要求递归解决方案:
(defun get-p0 (lst &optional (n 0))
(if (null lst)
nil
(let ((elt1 (first lst)) (eltn (cdr lst)))
(if (listp elt1)
(cons (get-p0 elt1) (get-p0 eltn))
(cons (if (= n 1) (+ elt1 2) elt1) (get-p0 eltn (+ n 1)))))))
所以
? (get-p0 '((A 1 2) (B 3 4)))
((A 3 2) (B 5 4))
如果有必要,它会进一步减少:
? (get-p0 '((A 0 2) ((B -4 4) (C 10 4))))
((A 2 2) ((B -2 4) (C 12 4)))
答案 2 :(得分:1)
你提出它的方式,你可以把问题看作一个基本的递归模式:你使用递归或迭代(mapcar
,reduce
等等来查看列表; dolist
,loop
等)并将函数应用于其条目。这是一个功能性解决方案:
(defun get-p0 (points)
(mapcar #'add-2 points))
其中辅助功能可以定义如下:
(defun add-2 (lst)
"Add 2 to the 2nd item"
(let ((res '()))
(do ((l lst (cdr l))
(i 1 (1+ i)))
((null l) (nreverse res))
(push (if (= 2 i)
(+ 2 (car l))
(car l))
res))))
答案 3 :(得分:0)
如你所写的“循环”使用不会返回任何内容;因此返回NIL。因为你的代码只是迭代x并计算某些东西;某些东西没有储存在任何地方。
那么,如何获得理想的结果呢?假设您愿意修改点中的每个点,这应该有效:
(defun get-p0 (points)
(loop for x from 0 to (- (list-length points) 1) do
(let ((point (nth x points)))
(setf (cadr point) (+ 2 (cadr point)))))
points)