【发布时间】:2013-11-06 16:49:09
【问题描述】:
作为练习,我尝试使用 Huffman 树对一些符号进行编码,但使用我自己的类而不是 Python 的内置数据类型。
这是我的节点类:
class Node(object):
left = None
right = None
weight = None
data = None
code = ''
length = len(code)
def __init__(self, d, w, c):
self.data = d
self.weight = w
self.code = c
def set_children(self, ln, rn):
self.left = ln
self.right = rn
def __repr__(self):
return "[%s,%s,(%s),(%s)]" %(self.data,self.code,self.left,self.right)
def __cmp__(self, a):
return cmp(self.code, a.code)
def __getitem__(self):
return self.code
这里是编码函数:
def encode(symbfreq):
tree = [Node(sym,wt,'') for sym, wt in symbfreq]
heapify(tree)
while len(tree)>1:
lo, hi = sorted([heappop(tree), heappop(tree)])
lo.code = '0'+lo.code
hi.code = '1'+hi.code
n = Node(lo.data+hi.data,lo.weight+hi.weight,lo.code+hi.code)
n.set_children(lo, hi)
heappush(tree, n)
return tree[0]
(请注意,data 字段最终将包含节点子节点中所有项目的set()。它只包含一个总和,而我得到正确的编码)。
这是我之前用于对树进行编码的函数:
def encode(symbfreq):
tree = [[wt, [sym, ""]] for sym, wt in symbfreq]
heapq.heapify(tree)
while len(tree)>1:
lo, hi = sorted([heapq.heappop(tree), heapq.heappop(tree)], key=len)
for pair in lo[1:]:
pair[1] = '0' + pair[1]
for pair in hi[1:]:
pair[1] = '1' + pair[1]
heapq.heappush(tree, [lo[0] + hi[0]] + lo[1:] + hi[1:])
return sorted(heapq.heappop(tree)[1:], key=lambda p: (len(p[-1]), p))
但是我注意到我的新过程是不正确的:它为顶部节点提供了最长的代码字而不是最终的叶子,并且不会为输入符号的排列生成相同的树,即以下不生成同一棵树(使用新的编码函数运行时):
input1 = [(1,0.25),(0,0.25),(0,0.25),(0,0.125),(0,0.125)]
input2 = [(0,0.25),(0,0.25),(0,0.25),(1,0.125),(0,0.125)]
我发现我在避免这种逐个/排序错误方面真的很糟糕 - 我将来如何解决这个问题?
【问题讨论】:
-
你能发布一些不好的输出吗?尤其是最后一部分。
-
一目了然,我怀疑您的错误在这里
lo, hi = sorted([heappop(tree), heappop(tree)])。这里的两个元素都是节点,您已将节点的__cmp__定义为cmp(self.code, a.code),但您尚未设置代码,因此它总是比较两个空字符串。我不确定堆是否真的是你需要的东西,你不只是将元素视为一个列表,从最小到最大排序吗?我忘记了霍夫曼编码是如何工作的,所以我不确定这是否是正确的方法。 -
@PatrickCollins 我在原始的“无类”代码中使用了一个堆,因为它总是首先弹出重量最低的项目(这就是创建霍夫曼树的方式)。问题是从第一个代码到一个类,在那里我犯了一个我无法纠正的错误 - 因为我不理解 cmp。
-
再一次,如果您使用数据结构的唯一原因是确保它已排序,那么我看不出与使用排序列表相比有什么优势。原始算法中树数据结构的要点是给你更快的解码,而不是编码。
-
@PatrickCollins 我将它用作统计算法的数据结构——它不适用于排序列表。
标签: python algorithm data-structures huffman-code