0

我将如何通过嵌套列表进行递归?

例如,给定:'((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。

4

4 回答 4

3

我会用这样的东西:

(loop for (letter x y) in '((A 1 2) (B 3 4))
     collect (list letter (+ 2 x) y))

原因:它更短,并且您不测量列表的长度以对其进行迭代(您为什么要这样做?)

于 2013-03-12T05:56:53.723 回答
3

由于您要求递归解决方案:

(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)))
于 2013-03-12T13:52:59.950 回答
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))))
于 2013-03-12T13:28:04.563 回答
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)
于 2013-03-12T02:38:03.153 回答