0

ネストされたリストを再帰するにはどうすればよいですか?

たとえば、次のようになります。'((A 1 2) (B 3 4))

ネストされた各サブリストの 2 番目の要素に 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

あなたは再帰的な解決策を求めているので:

(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 に答える
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 に答える
1

言い方を変えると、問題を基本的な再帰パターンと見なすことができます。再帰または反復 ( mapcarreduce、など; dolistloopなど) を使用してリストを調べ、そのエントリに関数を適用します。機能的なソリューションは次のとおりです。

(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 に答える