Я пытаюсь понять код Хаффмана, написанный на python под «кодом Розетты». Ниже приведена небольшая часть кода.

def encode(symb2freq):
    heap = [[wt, [sym, ""]] for sym, wt in symb2freq.items()] #What does this do?

Я предполагаю, что переменная heap является списком. Но что такое wt и sym?

1
Sabih 17 Дек 2015 в 01:38

4 ответа

Лучший ответ

sym2freq - это словарь с ключами, некоторыми символами и их значениями частоты символа. Например, если у вас есть строка «aaabacba», словарь будет выглядеть следующим образом

sym2freq = {'a': 5, 'b': 2, 'c': 1}

Это потому, что у нас есть 5 раз буква а, 2 раза буква b и 1 раз буква c.

У словарей есть метод items(), который будет возвращать кортеж каждого ключа с соответствующим значением. В нашем случае он вернется

>>> sym2freq.items()
(('a', 5), ('b', 2), ('c', 1))

for sym, wt in symb2freq.items() часть списка понимания просто распаковывается. Каждый раз, когда мы выбираем один из наших кортежей сверху, мы назначаем первый объект переменной sym, а второй - переменной wt. Названия sym и wt были выбраны исключительно для отражения значений, которые представляют, то есть символа и веса (частоты).

>>> sym, wt = ('a', 5)
>>> print sym
'a'
>>> print wt
5

И так как понимание списка создаст списки структуры [wt, [sym, ""]], вы получите список

>>> encode(sym2freq)
[[5, ['a', '']], [2, ['b', '']], [1, ['c', '']]]

Причина, по которой мы переходим от словаря частот символов к структуре, подобной списку heap, заключается в том, что мы можем сортировать символы по их частотам, что, как вы изучаете, является частью построения дерева Хаффмана.

3
Reti43 16 Дек 2015 в 23:19

Это интересная проблема. Представьте себе словарь из пяти букв, где ключ - это буква, а значение - частота:

a = {'a':1, 'b':2, 'c':3, 'd':4, 'e':5}

Затем сопоставьте его так, чтобы он представлял собой список списков с частотой и список, начинающийся с буквы в переменной кучи, например:

[[1, ['a', '']], [2, ['b', '']], [3, ['c', '']], [4, ['d', '']], [5, ['e', '']]]

Затем, когда вы его накапливаете, вы получаете:

[[1, ['a', '']],
 [3, ['c', '']],
 [2, ['b', '']],
 [5, ['e', '']],
 [4, ['d', '']]]

Просто поработайте шаг за шагом с действительным словарем для кодирования, подобным приведенному на странице википедии, и вы сможете увидеть, что делает каждый шаг. Или используйте тривиальный пример, чтобы начать как тот, который я дал, и постепенно увеличивайте количество элементов, пока вы не работаете с реальным документом.

Код Розетты выполняет итерацию в куче и добавляет цифры к пустой строке, которую вы видите после буквы, основываясь на частоте, до тех пор, пока каждая буква не будет преобразована в двоичную интерпретацию. Итак, в конце концов вы получите что-то вроде этого:

 [['e', '101'], 
  ['d', '010'], 
  ['c', '1001'], 
  ['b', '1100'], 
  ['a', '1101']]

Где самые частые буквы требуют наименьшего количества бит.

-1
Rob 16 Дек 2015 в 23:04

Это понимание списка. Это говорит

  • Возьмите предметы из symb2freq и начните их перебирать.
  • Получите первый элемент в symb2freq и распакуйте его в переменные sym и wt.
  • Теперь добавьте [wt, [sym, ""]] в список
  • Сделайте это для каждого предмета
  • Теперь поместите список в переменную heap

Например, [bar(x) for x in foo] создает список, который применяет bar(x) к каждому значению в списке.

2
noɥʇʎԀʎzɐɹƆ 16 Дек 2015 в 22:45

Sym - символ, а wt - вес.

https://en.wikipedia.org/wiki/Huffman_coding

-3
chinglun 16 Дек 2015 в 22:44