这很有趣!
好吧,我真的很希望那不是功课。原来,有一个非常简单的递归解决方案。你想在每个级别上取得树木清单,成对收集到一个更深的树木,然后在这个级别追加新的树叶。这可以使用'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