Open Source WEB

##(link2sicp "book-Z-H-22.html#%_thm_3.19" "Exercise 3.19")

解答例

対象となるリストに対して、cdr及びcddrを繰り返し、 その都度eq?で両者を比較する。循環している場合、cddrが cdrに追いつき、循環していると判定される。

(define (loop-check x)
  (define (check x0 x1)
    (cond ((eq? x0 x1) true)
          ((null? (cdr x1)) false)
          ((null? (cddr x1)) false)
          (else (check (cdr x0) (cddr x1)))))
  (if (and (pair? x) (pair? (cdr x)))
      (check (cdr x) (cddr x))
      false))

実行例

gosh> (loop-check '(a b c))
#f
gosh> (define z (make-cycle (list 'a 'b 'c)))
z
gosh> (loop-check z)
#t

問題18同様、carで循環しているようなリストに対しては loop-checkで循環を判別できない。

gosh> (define c (list 'foo))
c
gosh> (define ll (cons 'foo (cons 'foo c)))
ll
gosh> (set-car! c ll)
#<undef>
gosh> (loop-check c)
#f
gosh> c
#0=((foo foo . #0#))

--hidenao

コード

##(sicp-answer-code "ex-3.19.scm")

このサイトは、 IPA の「平成15年度オープンソフトウエア活用基盤整備事業」 の委託事業として開発されたKahuaで試験的に運用しております。

Copyright (c) 2004-2007 株式会社タイムインターメディア About Us