Алгоритм Хаффмана, кодировка битов - Pascal ABC
Формулировка задачи:
Здравствуйте! Есть ДЗ по информатике - создать программу на Pascal ABCnet, которая сжимает файл по алгоритму Хаффмана.
Я сначала написал программу хотя бы создания дерева и словаря, чтобы была основа, и думал, что с битами разберусь позже. Дело в том, что нам вообще ничего не рассказывали про саму кодировку, и если на Си я нашел очень много информации по тому, как можно менять биты внутри байтового символа, например, то на Паскале я так и не нашел решения..
В общем, ниже представлена программа, которая кодирует ТЕКСТОВЫЙ файл по алгоритму Хаффмана (текстовый или нет - не важно, это я, скорее всего, поменяю), и она заменяет один байт символа на пять-шесть байт последовательностей цифр D А нужно, чтобы эти цифры вгонялись в биты.
Плюс преподаватель рассказывал, что обратная программа (разархиватор) идет по коду, находит префиксный код и прекращает чтение, переключается на следующий "байт" как бы, а найденный заменяет числом. Но я не представляю, как можно сделать так, чтобы читались БИТЫ, и если находится последовательность БИТ из 4 штук, то все это прекращалось. Пожалуйста, просветите невежду!
Буду очень благодарен, если хотя бы расскажете, как мне это сделать (я не прошу именно менять что-то в программе). Просто на основе моих замен объяснить, как то же самое запихнуть внутрь байта. Я знаю лишь shr и shl, но не смог придумать применения этому(
Еще самое обидное, что дедлайн передвинули на 10 дней ближе, и теперь вообще все плохо..
Решение задачи: «Алгоритм Хаффмана, кодировка битов»
textual
Листинг программы
Mask:=$80; CurrByte:=0; while (ещё есть символы в тексте) do begin CurrChar:=GetNextCharFromText(); //берём следующий символ из текста for i:=1 to (длина кода символа CurrChar) do begin if GetBit(CurrChar, i)=1 then //если i-ый бит в коде символа CurrChar равен 1 begin CurrByte:=CurrByte or Mask; //устанавливаем этот бит в выходном байте end; Mask:=Mask shr 1; // смещаем маску к следующей позиции в байте if Mask=0 then // если мы полностью заполнили байт begin write(tfOut, CurrByte); // то сохраняем байт в файле Mask:=$80; // и начинаем заполнять следующий байт CurrByte:=0; end; end; end; if Mask<>$80 then // если остались несохранённые биты, write(tfOut, CurrByte); // то сохраняем байт в файле
Объяснение кода листинга программы
- Mask:=$80; — устанавливаем начальное значение маски
- CurrByte:=0; — устанавливаем начальное значение выходного байта
- while (ещё есть символы в тексте) do — цикл, пока есть символы в тексте
- CurrChar:=GetNextCharFromText(); — получаем следующий символ из текста
- for i:=1 to (длина кода символа CurrChar) do — цикл, пока длина кода символа CurrChar не превысит i
- if GetBit(CurrChar, i)=1 then — проверяем i-ый бит в коде символа CurrChar
- CurrByte:=CurrByte or Mask; — устанавливаем этот бит в выходном байте
- Mask:=Mask shr 1; — смещаем маску к следующей позиции в байте
- if Mask=0 then — если мы полностью заполнили байт
- write(tfOut, CurrByte); — сохраняем байт в файле
- Mask:=$80; — устанавливаем начальное значение маски
- CurrByte:=0; — устанавливаем начальное значение выходного байта
- end; — закрываем цикл, пока остались несохранённые биты
- if Mask<>$80 then — если остались несохранённые биты
- write(tfOut, CurrByte); — сохраняем байт в файле
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д