使用bitarray
模块,您可以免费获得哈夫曼编码和解码功能,而且可能比其他任何工具都更高效:
from bitarray import bitarray
huffman_dict = {
'!': bitarray('01110'), 'B': bitarray('01111'),
'l': bitarray('10100'), 'q': bitarray('10110'),
'y': bitarray('10111')
}
a = bitarray()
a.encode(huffman_dict, 'Bylly!')
print(a)
dec = bitarray('011111011101110').decode(huffman_dict)
print(dec)
print(''.join(dec))
如果您不想安装该模块,请阅读下面的部分。
这里有一种使用哈夫曼树进行解码的变体 - 程序可以运行,但可能有更好的变体来表示二叉树(我选择了元组)。
当您的编码字不全是相同长度时,这个版本可能更适合。二叉树的另一个好处是,在这里很明显代码是前缀自由的。
您的树形代码如下所示(过度缩进以使树形结构可见):
huffman_tree = \
( # 0
( # 00
None,
# 01
( # 010
None,
# 011
( # 0110
None,
# 0111
( # 01110
'!',
# 01111
'B')))),
# 1
( # 10
( # 100
None,
# 101
( # 1010
( # 10100
'l',
# 10101
None
),
# 1011
( # 10110
'q',
# 10111
'y'))),
# 11
None))
使用它,然后可以解码:
def huffman_decode(strg):
ret = ''
cur_node = huffman_tree
for char in strg:
cur_node = cur_node[int(char)]
if cur_node is None:
raise ValueError
elif isinstance(cur_node, str):
ret += cur_node
cur_node = huffman_tree
return ret
print(huffman_decode('011111011101110'))
如果解码遇到
None
,则会出现错误并引发
ValueError
。一旦解码遇到字符串,当前节点
cur_node
就会重置为“根节点”,游戏将从树的开头开始。
只是因为我可以:这里是您(不完整的)哈夫曼树的可视化显示(这可能有助于理解算法的工作原理:每当您遇到一个
0
时:向右下方移动;每当您遇到一个
1
时:向右上方移动)。如果您到达了叶节点:返回该节点处的字符并重新从根节点开始。
011111011101110
->01111
= B,10111
= y,以及01110
= !,根据你自己的表格都是正确的。 - Jongware