с помощью 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_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' = !, все правильно в соответствии с вашей собственной таблицей. – usr2564301