我根据以下输入分布生成霍夫曼代码:
a = [(1,0.5),(0,0.25),(0,0.125),(0,0.125)]
b = [(0,0.5),(1,0.25),(0,0.125),(0,0.125)]
唯一的区别是1是在不同的bin中。
但是当我使用以下函数对它们进行编码时:
def encode(symbfreq):
tree = [[wt, [sym, ""]] for sym, wt in symbfreq]
heapq.heapify(tree)
while len(tree)>1:
lo, hi = heapq.heappop(tree), heapq.heappop(tree)
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))
我为分发获得了不同的代码字:
a = [[1, '1'], [0, '00'], [0, '010'], [0, '011']]
虽然
b = [[0, '0'], [1, '11'], [0, '100'], [0, '101']]
为什么我会有这种差异?
供参考:我需要将树分成左右分支(基于左分支,以1开头,右边为0)作为尝试找到1.在第一种情况下,我的算法应该需要1次迭代,然后是第2次2.但是,因为每个bin都返回的代码字不同,每次两个版本当前都需要2次迭代才能找到1 - 这不是我想要的!
答案 0 :(得分:3)
尽管它们看起来不同,但结果是正确的,并且等效。
您可以通过对lo
和hi
分支进行排序来使它们看起来相同,这样您就可以通过替换以下内容将1
添加到更大的分支:
lo, hi = heapq.heappop(tree), heapq.heappop(tree)
使用:
lo, hi = sorted([heapq.heappop(tree), heapq.heappop(tree)], key=len)
结果
>>> encode(a)
3: [[1, '0'], [0, '10'], [0, '110'], [0, '111']]
>>> encode(b)
4: [[0, '0'], [1, '10'], [0, '110'], [0, '111']]