SICP学习笔记 第二章 (2.3)

基本过程:

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)个二进制位。

原文地址:https://www.cnblogs.com/sungoshawk/p/2765103.html