這很有趣!
好吧,我真的很希望那不是功課。原來,有一個非常簡單的遞歸解決方案。你想在每個級別上取得樹木清單,成對收集到一個更深的樹木,然後在這個級別追加新的樹葉。這可以使用'foldr'來書寫,但我認爲它會有點不太清楚。
我應該澄清一點輸入;你提到的頁面上,規格看起來像
葉0級:
葉1級:
葉等級2:X23,X42,X23
離開第3級:X24,X23
這將對應於輸入
「(()()(X23 X42 X23)(X24 X23))
下面的程序。
另外,這裏唯一要做的就是將此表映射到二叉樹,這僅在解碼時纔有用。對於編碼,這個二叉樹將是無用的。
最後,大喊一聲給How To Design Programs;我仔細地遵循了設計方案,把我所有的東西都打成一團,然後穿過我所有的東西。請先測試用例!
乾杯!
約翰克萊門特
#lang racket
(require rackunit)
;; a tree is either
;; a symbol, or
;; (list tree tree)
;; a specification is
;; (listof (listof symbol))
;; spec->tree : specification -> tree
;; run spec->treelist, ensure that it's a list of length 1, return it.
(define (spec->tree spec)
(match (spec->treelist spec)
[(list tree) tree]
[other (error 'spec->tree "multiple trees produced")]))
;; spec->treelist : specification -> (listof tree)
;; given a *legal* specification, produce
;; the corresponding tree. ONLY WORKS FOR LEGAL SPECIFICATIONS...
(define (spec->treelist spec)
(cond [(empty? spec) empty]
[else (append (first spec) (gather-pairs (spec->treelist (rest spec))))]))
;; go "up one level" by grouping each pair of trees into one tree.
;; The length of the list must be a number divisible by two.
(define (gather-pairs trees)
(match trees
[(list) empty]
[(list-rest a b remaining) (cons (list a b) (gather-pairs remaining))]
[other (error 'gather "improperly formed specification")]))
;; TEST CASES
(check-equal? (gather-pairs '(a b c d)) '((a b) (c d)))
(check-equal? (spec->treelist '((top))) '(top))
(check-equal? (spec->treelist '(() (two-a two-b))) '((two-a two-b)))
(check-equal? (spec->treelist '(() (two-a) (three-a three-b)))
'((two-a (three-a three-b))))
(check-equal? (spec->treelist '(()() (three-a three-b three-c) (four-a four-b)))
'(((three-a three-b) (three-c (four-a four-b)))))
(check-equal? (spec->tree '(()() (three-a three-b three-c) (four-a four-b)))
'((three-a three-b) (three-c (four-a four-b))))
你能否提供一些細節?我認爲你的意思是建立一個基於一定頻率出現的霍夫曼樹。我認爲這應該是不同的,因爲只有一定的數量說明了一定長度的多少位串。 – 2011-04-17 09:33:15
完成,我不是一個計劃編碼器,哈夫曼樹也不是很容易。 – Bytemain 2011-04-17 09:41:24