by shigemk2

当面は技術的なことしか書かない

リスト遊び 4-4 再帰とリスト

前回
リスト遊び 4-3 フィボナッチ数列 - by shigemk2

再帰の定石(リスト編)

  • 終了条件を調べ、終了なら初期値を返す
  • リストの先頭の要素(car)に対して仕事をする
  • リストの残り(cdr)と共に自分自身を呼び出す

(リストの場合、carは要素で、cdrはリストになることに注意する)

;; リスト内の整数の総和を求める
(defun sum (lst)
  (cond
   ((null lst) 0)
   (t (+ (car lst) (sum (cdr lst))))))
sum
(sum '(1 3 7))
11

;; 置換と削除の関数は、再帰と条件分岐を使って必要な要素をどんどんconsしていってるのがポイント
;; 置換
(defun repl (lst old new)
  (cond
   ((null lst) nil)
   ((eq (car lst) old) ;; 
    (cons new (repl (cdr lst) old new)))
   (t (cons (car lst) (repl (cdr lst) old new)))))
repl
(repl '(dog pig dog) 'dog 'rat)
(rat pig rat)
;; eq使って比較しているから、文字列のリストだとこの関数は使えない
(repl '("dog" "pig" "dog") 'dog 'rat)
("dog" "pig" "dog")

;; 削除
(defun del (x lst)
  (cond
   ((null lst) nil)
   ((eq (car lst) x) (del x (cdr lst)))
   (t (cons (car lst) (del x (cdr lst))))))
del
(del 'pig '(rat dog pig))
(rat dog)

リスト遊び―Emacsで学ぶLispの世界 (ASCII SOFTWARE SCIENCE Language)

リスト遊び―Emacsで学ぶLispの世界 (ASCII SOFTWARE SCIENCE Language)