EoPL reading (12) 1.2.4 Exercises
Exercise 1.17-1
二分探索木を parse するナニ。最初、ついクセで cdr 使ってしまった。REPL で色々確認。
gosh> (define l '(14 (7 () (12 () ())) (26 (20 (17 () ()) ()) (31 () ())))) l gosh> l (14 (7 () (12 () ())) (26 (20 (17 () ()) ()) (31 () ()))) gosh> (car l) 14 gosh> (cadr l) (7 () (12 () ())) gosh> (cddr l) ((26 (20 (17 () ()) ()) (31 () ()))) gosh> (caddr l) (26 (20 (17 () ()) ()) (31 () ())) gosh>
ええと左の部分木は cadr で右の部分木は caddr で良い?
で、以下な実装。
(define (path n bst) (define (path-inner rslt l) (cond ((equal? n (car l)) rslt) ((< n (car l)) (path-inner (cons 'left rslt) (cadr l))) ((> n (car l)) (path-inner (cons 'right rslt) (caddr l)))) ) (path-inner '() bst) )
試験してみたら以下。
$ make Testing path ... failed. discrepancies found. Errors are: test (path 17 '(14 (7 () (12 () ())) (26 (20 (17 () ()) ()) (31 () ())))) should return (right left left): expects (right left left) => got (left left right) $
とほほ。cons してるから逆に積まれるのか。これって再起でナニするとどうなるんかな。
(define (path n bst) (cond ((equal? n (car bst)) '()) ((< n (car bst)) (cons 'left (path n (cadr bst)))) ((> n (car bst)) (cons 'right (path n (caddr bst))))) )
こっちの方が簡潔ですな。ちなみに繰り返し版が以下。
(define (path n bst) (define (path-inner rslt l) (cond ((equal? n (car l)) (reverse rslt)) ((< n (car l)) (path-inner (cons 'left rslt) (cadr l))) ((> n (car l)) (path-inner (cons 'right rslt) (caddr l)))) ) (path-inner '() bst) )
reverse してます。微妙。