基本过程:
1 (eq? <symbol1> <symbol2>) ;判断连个符号是否相同 2 (cadr <list>) => (car (cdr <list>)) 3 (number? <num>) 4 (symbol? <sym>)
范例:霍夫曼编码树
定长编码(fixed-length codes):采用同样数目的二进制位表示消息中的每个字符。
变长编码(variable-length codes):采用不同数目的二进制位表示不同字符。
前缀码(prefix code):每个字符的完整编码都不是另一字符的开始一段。
霍夫曼编码:Huffman编码可以表示为一棵二叉树,树叶是被编码的符号。非叶子节点代表一个集合,其中包含了这一节点下所有叶子节点的符号。位于叶子节点的符号还被赋予一个权重(相对频度),非叶节点的权重是其下所有叶节点的权重之和。
一棵霍夫曼树:
部分习题:
exercise 2.54
1 (define (equal? a b) 2 (cond ((and (null? a) (null? b)) #t) 3 ((and (null? a) (not (null? b))) #f) 4 ((and (not (null? a)) (null? b)) #f) 5 (else (let ((fir-a (car a)) 6 (fir-b (car b))) 7 (cond ((or (and (pair? fir-a) (not (pair? fir-b))) 8 (and (not (pair? fir-a)) (pair? fir-b))) 9 #f) 10 ((and (pair? fir-a) (pair? fir-b)) 11 (equal? fir-a fir-b)) 12 (else (if (eq? fir-a fir-b) 13 (test (cdr a) (cdr b)) 14 #f)))))))
exercise 2.55
exercise 2.56
1 (defien (exponentiation? exp) 2 (and (pair? exp) (eq? (car exp) '**))) 3 (define (make-exp base exponent) 4 (cond ((= exponent 0) 1) 5 ((= exponent 1) base) 6 (else (list '** base exponent)))) 7 (define (base exp) 8 (car exp)) 9 (define (exponent exp) 10 (caddr exp)) 11 12 (define (deriv exp var) 13 (cond ((number? exp) 0) 14 ((variable? exp) 15 (if (same-variable? exp var) 1 0)) 16 ((sum? exp) 17 (make-sum (deriv (addend exp) var) 18 (deriv (augend exp) var))) 19 ((product? exp) 20 (make-sum (make-product (multiplier exp) 21 (deriv (multiplicand exp) var)) 22 (make-product (deriv (multiplier exp) var) 23 (multiplicand exp)))) 24 ((exponentiation? exp) 25 (make-product (make-product (exponent exp) 26 (make-exp (base exp) (- (exponent exp) 1))) 27 (deriv (base exp) var))) 28 (else (error "unknown expression" exp))))
exercise 2.57
将 y 看为常数,则算式 d[x * y * (x + 3)] / dx = 2xy + 3y 。
1 (define (length exp) 2 (if (null? exp) 3 0 4 (length (cdr exp)))) 5 (define (augend s) 6 (if (> (length s) 3) 7 (cons (car s) 8 (cdr (cdr s))) 9 (caddr s))) 10 (define (multiplicand p) 11 (if (> (length p) 3) 12 (cons (car p) 13 (cdr (cdr p))) 14 (caddr p)))
exercise 2.59
1 (define (union-set set1 set2) 2 (cond ((null? set1) set2) 3 ((not (element-of-set? (car set1) set2)) 4 (cons (car set1) 5 (union-set (cdr set1) set2))) 6 (else (union-set (cdr set1) set2))))
exercise 2.61
1 (define (adjoin-set x set) 2 (if (null? set) 3 (list x) 4 (let ((var (car set))) 5 (cond ((= x var) set) 6 ((> x var) 7 (cons var 8 (adjoin-set x (cdr set)))) 9 (else (cons x set))))))
exercise 2.62
1 (define (union-set set1 set2) 2 (cond ((and (null? set1) (null? set2)) '()) 3 ((null? set1) set2) 4 ((null? set2) set1) 5 (else (let ((x1 (car set1)) 6 (x2 (car set2))) 7 (cond ((= x1 x2) 8 (cons x1 (union-set (cdr set1) (cdr set2)))) 9 ((< x1 x2) 10 (cons x1 (union-set (car set1) set2))) 11 ((> x1 x2) 12 (cons x2 (union-set set1 (cdr set2)))))))))
exercise 2.67
exercise 2.68
1 (define (encode-symbol symbol tree) 2 (if (leaf? tree) 3 '() 4 (let ((left (left-branch tree)) 5 (right (right-branch tree))) 6 (cond ((find-symbol? symbol (symbols left)) 7 (cons 0 (encode-symbol symbol left))) 8 ((find-symbol? symbol (symbols right)) 9 (cons 1 (encode-symbol symbol right))) 10 (else (error "no this symbol" symbol)))))) 11 (define (find-symbol? symbol symbol-list) 12 (cond ((null? symbol-list) #f) 13 ((eq? symbol (car symbol-list)) #t) 14 (else (find-symbol? symbol (cdr symbol-list)))))
exercise 2.69
1 (define (successive-merge leafs) 2 (cond ((< (length leafs) 2) (error "not enough leafs")) 3 ((= (length leafs) 2) 4 (make-code-tree (car leafs) 5 (cadr leafs))) 6 (else (make-code-tree (car leafs) 7 (successive-merge (cdr leafs)))))) 8 (define (generate-huffman-tree pairs) 9 (successive-merge (reverse (make-leaf-set pairs))))
exercise 2.70
对应的Huffman树,看起来是对的,有待验证。
符号编码:
a | 1110 | na | 0 |
boom | 1111110 | sha | 110 |
get | 11110 | yip | 10 |
job | 111110 | wah | 1111111 |
exercise 2.71
最频繁的符号用1个二进制位,最不频繁的符号用(n - 1)个二进制位。