Advertisement
Guest User

Untitled

a guest
Nov 17th, 2019
131
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.92 KB | None | 0 0
  1. Encode
  2. 1. Один раз проходимся по входным данным, считая частотности букв алфавита. Так как пройтись придется дважды, надо запомнить весь ввод.
  3. 2. Для всех букв с ненулевой частотностью создаем узел дерева Хаффмана, где храним частотность, букву, указатели на левого и правого потомков. Кладем каждый узел в очередь с приоритетом (min Heap по частотности).
  4. 3. Пока в куче более одного элемента, достаем из нее по 2 узла на каждой итерации. Создаем новый узел, к которому правым и левым дочерним элементом цепляем извлеченные только что узлы, а в частотность пишем сумму их частотностей. Кладем этот новый узел в кучу. Когда в куче останется один элемент -- это корень построенного дерева Хаффмана.
  5. 4. Строим по дереву Хаффмана таблицу кодов, где каждому кодируемому символу алфавита ставится в соответствие вектор битов -- его код. Для этого обходим дерево в глубину, попутно тащим за собой вектор пути (пошли направо -- добавляем 1, пошли налево -- 0), как только дошли до листа -- пишем в таблицу символ и битовый путь к нему.
  6. 5. Чтобы впоследствии раскодировать данные, понадобится в самом сообщении передать построенное дерево. Можно сделать это так:
  7. 5.1 Пишем байт с числом символов алфавита.
  8. 5.2. В корне дерева Хаффмана начинаем алгоритм:
  9. Текущий узел лист? Пишем бит "1" и байт с символом алфавита.
  10. Текущий узел внутренний? Рекурсивно вызываем эту функцию для левого поддерева, для правого поддерева, затем пишем бит "0"
  11. 6. Кодируем исходное сообщение при помощи таблицы. Смотрим код для очередного символа -- пишем его побитово. Чтобы знать, сколько в последнем байте закодированного сообщения значащих бит, надо как-то передать это. Можно это записать в самом последнем байте вывода, после закодированного сообщения. Можно посчитать заранее (у нас есть частотность каждого символа и длина его кода), записать после 5.1 или вообще самым первым байтом вывода. Вариантов масса. Главное, не забыть.
  12.  
  13. Decode
  14. 1. Читаем дерево
  15. 1.1. Читаем байт с числом букв алфавита.
  16. 1.2. Начинаем читать само дерево. Нам понадобится стек. Алгоритм:
  17. Пока не прочитали столько букв, сколько их в кодируемом алфавите, и пока в стеке более одного узла, читаем бит.
  18. Прочитали 1? Читаем еще байт, там символ кодируемого алфавита. Создаем узел дерева Хаффмана с этим символом, кладем узел в стек.
  19. Прочитали 0? Достаем из стека два узла, создаем новый, к которому цепляем извлеченные узлы (первый извлеченный -- правый потомок, второй -- левый). Кладем новый узел в стек.
  20. Мы восстановили дерево Хаффмана.
  21. 3. Теперь идет закодированная последовательность. Читаем побитово, обходим дерево Хаффмана от корня к листьям (прочитали 1 -- идем вправо, 0 -- влево). Дошли до листа -- декодировали очередной символ, пишем его. Не забываем вовремя остановиться, последний байт кодовой последовательности может содержать мусорные биты.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement