使用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))
# # output:
# bitarray('011111011110100101001011101110')
# ['B', 'y', '!']
# By!
如果您不想安装该模块,请阅读以下部分。
这是一个使用 huffman 树 进行解码的变体 - 该程序可以工作,但可能有更好的变体来表示二叉树(我选择了一个元组)。
当您的代码字长度不同时,此版本可能更适合。二叉树的另一个好处是,这里的代码很明显是无前缀的。
您的树形代码如下所示(过度缩进以使树形结构可见):
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:向右+向下;每当你遇到@987654332 @: 向右+向上);如果你击中一个结束节点:返回该节点的字符并在根节点重新启动。