Created
December 20, 2012 08:16
-
-
Save yao2030/4343738 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(define (memq item x) | |
(cond ((null? x) false) | |
((eq? item (car x)) x) | |
(else (memq item (cdr x))))) | |
;; huffman coding (information theory) | |
(define (make-leaf symbol weight) | |
(list 'leaf symbol weight)) | |
(define (leaf? object) | |
(eq? (car object) 'leaf)) | |
(define (symbol-leaf x) (cadr x)) | |
(define (weight-leaf x) (caddr x)) | |
(define (make-code-tree left right) | |
(list left | |
right | |
(append (symbols left) (symbols right)) | |
(+ (weight left) (weight right)))) | |
(define (left-branch tree) (car tree)) | |
(define (right-branch tree) (cadr tree)) | |
(define (symbols tree) | |
(if (leaf? tree) | |
(list (symbol-leaf tree)) | |
(caddr tree))) | |
(define (weight tree) | |
(if (leaf? tree) | |
(weight-leaf tree) | |
(cadddr tree))) | |
;; decoding procedure | |
(define (decode bits tree) | |
(define (decode-1 bits current-branch) | |
(if (null? bits) | |
'() | |
(let ((next-branch (choose-branch (car bits) current-branch))) | |
(if (leaf? next-branch) | |
(cons (symbol-leaf next-branch) | |
(decode-1 (cdr bits) tree)) | |
(decode-1 (cdr bits) next-branch))))) | |
(decode-1 bits tree)) | |
(define (choose-branch bit branch) | |
(cond ((= bit 0) (left-branch branch)) | |
((= bit 1) (right-branch branch)) | |
(else (error "bad bit -- CHOOSE-BRANCH" bit)))) | |
(define (adjoin-set x set) | |
(cond ((null? set) (list x)) | |
((< (weight x) (weight (car set))) (cons x set)) | |
(else (cons (car set) | |
(adjoin-set x (cdr set)))))) | |
(define (make-leaf-set pairs) | |
(if (null? pairs) | |
'() | |
(let ((pair (car pairs))) | |
(adjoin-set (make-leaf (car pair) ;symbol | |
(cadr pair)) ;frequency | |
(make-leaf-set (cdr pairs)))))) | |
;; 2.67 sample | |
(define sample-tree | |
(make-code-tree (make-leaf 'A 4) | |
(make-code-tree | |
(make-leaf 'B 2) | |
(make-code-tree (make-leaf 'D 1) | |
(make-leaf 'C 1))))) | |
(define sample-message '(0 1 1 0 0 1 0 1 0 1 1 1 0)) | |
;; 2.68 encode | |
(define (encode message tree) | |
(if (null? message) | |
'() | |
(append (encode-symbol (car message) tree) | |
(encode (cdr message) tree)))) | |
(define (encode-symbol symbol tree) | |
(cond ((leaf? tree) '()) | |
((memq symbol (symbols tree)) | |
(let ((right (right-branch tree)) | |
(left (left-branch tree))) | |
(cond ((and (leaf? right) (not (eq? symbol (symbol-leaf right)))) (cons 0 (encode-symbol symbol left))) | |
((and (leaf? left) (not (eq? symbol (symbol-leaf left)))) (cons 1 (encode-symbol symbol right))) | |
((if (memq symbol (symbols right)) | |
(cons 1 (encode-symbol symbol right)) | |
(cons 0 (encode-symbol symbol left))))))) | |
(else (error "DON'T KNOW TO HOW TO ENCODE" symbol)))) | |
;; 2.69 | |
(define (generate-huffman-tree pairs) | |
(successive-merge (make-leaf-set pairs))) | |
(define (successive-merge ordered-pairs) | |
(if (null? (cdr ordered-pairs)) | |
(car ordered-pairs) | |
(successive-merge (adjoin-set (make-code-tree (car ordered-pairs) (cadr ordered-pairs)) (cddr ordered-pairs))))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
SICP