2.3.3 Example: Representing Sets
http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-16.html#%_sec_2.3.3
集合の操作として、
- 順序づけられていない集合の場合
- 順序づけた集合の場合
- Binary Treeとして現した場合
の三種類がでてくるとこ。
問題自体も大して難しくなく、全体的にスルーしてもいいかなぁ、という印象。
問題2.59
union-set(和集合)
(define (union-set set1 set2) (cond ((null? set1) set2) ((null? set2) set1) ((not (element-of-set? (car set1) set2)) (cons (car set1) (union-set (cdr set1) set2))) (else (union-set (cdr set1) set2))))
問題2.60
重複するリストの場合のそれぞれの操作。
(define adjoin-set cons) (define union-set append)
効率は、より長いリストを操作するので悪くなる。
重複リストが優位な応用って何だろう??? でも、実際の現場では重複していることの方が多いか。
問題2.61
順序づけされたリストのadjoin-set
(define (adjoin-set x set) (cond ((null? set) (list x)) ((= x (car set)) set) ((< x (car set)) (cons x set)) (else (cons (car set) (adjoin-set x (cdr set))))))
問題2.62
順序づけられたリストのunion-set
(define (union-set set1 set2) (cond ((null? set1) set2) ((null? set2) set1) (else (let ((x1 (car set1)) (x2 (car set2))) (cond ((= x1 x2) (cons x1 (union-set (cdr set1) (cdr set2)))) ((< x1 x2) (cons x1 (union-set (cdr set1) set2))) ((< x2 x1) (cons x2 (union-set set1 (cdr set2)))))))))
問題2.63
a. 同じ結果になる。
b. tree->list1はリストの連結にappendを使用しているため、appendの操作にO(n)の計算量が余計に必要となる。
問題2.64
a. リストを真ん中の要素で半分に分割する。右側の先頭値をBinary Treeの先頭とし、左側と右側のリストをそれぞれ再帰的にBinary Treeに変換する。
b. O(n)でいいのかな。
問題2.65
Binary Tree版のunion-setとintersection-set。Binary Treeをリストに変換して、リスト操作をして、リストをBinary Treeに変換する。
(define (union-set set1 set2) (list->tree (union (tree->list set1) (tree->list set2))) (define (union l1 l2) (cond ((null? l1) l2) ((null? l2) l1) (else (let ((h1 (car l1)) (h2 (car l2))) (cond ((= h1 h2) (cons h1 (union (cdr l1) (cdr l2)))) ((< h1 h2) (cons h1 (union (cdr l1) l2))) ((< h2 h1) (cons h2 (union l1 (cdr l2))))))))))
(define (intersection-set set1 set2) (list->tree (intsersection (tree->list set1) (tree->list set2))) (define (intersection l1 l2) (cond ((null? l1) l2) ((null? l2) l1) (else (let ((h1 (car l1)) (h2 (car l2))) (cond ((= h1 h2) (cons h1 (intersection (cdr l1) (cdr l2)))) ((< h1 h2) (intersection (cdr l1) l2)) ((< h2 h1) (intersection l1 (cdr l2)))))))))
問題2.66
レコードになっている場合のlookup.
(define (lookup given-key set-of-records) (cond ((null? set-of-records) #f) ((= given-key (key (entry set-of-records))) (entry (set-of-records))) ((< given-key (key (entry set-of-records))) (element-of-set? given-key (left-branch set-of-records))) ((> given-key (key (entry set-of-records))) (element-of-set? given-key (right-branch set-of-records)))))