2) в виде урезанного представления дерева Хаффмана – 2*N–1 троек <символ, левый, правый>, где
символ — ASCII код символа входного алфавита или 0 для псевдосимвола (1 байт),
левый — номер левого сына в дереве для данной вершины (1 байт),
правый — номер правого сына в дереве для данной вершины (1 байт).
Кодирование основного текста можно представить в виде следующей последовательности действий.
Пусть нам дано дерево Хаффмана, построенное в лабораторной работе №11.
Шаг 0.
b := 0;
i := 0;
Шаг 1. Считать их входного файла в переменную c очередной символ.
Найти такое k, что Т[k].символ = с, 1 £ k £ N.
s := T[k].код;
L := длина(s);
j := 1;
пока j £ L выполнять
{ i := i + 1;
если S[j]=’1’
то setbit(&b, i);//i-му биту в b присвоить 1
если i = 8
то {
записать b в выходной файл;
b := 0;
i := 0;
}
j := j + 1;
}
Шаг 2.
Если входной файл не пуст, то перейти на Шаг2.
если i > 0
то записать b в выходной файл.
Конец.
Приведем реализацию функции setbit на Си.
void setbit (unsigned char *b, int i)
{
*b |= 1<<(8-i);
}
Написать программу, которая декодирует заданный файл, заархивированный методом сжатия по Хаффману.
Входные данные
На вход программе подается заархивированный файл.
Выходные данные
Нужно вывести в выходной файл исходный декодированный текст.
Метод
Считать из входного файла длину исходного закодированного файла и записать в переменную L.
Считать из входного файла в переменную N целое число (1 байт) — размер алфавита.
Восстановить дерево Хаффмана (будем использовать массив T, описанный в лабораторной работе № 12):
i := 0;
пока i < N*2 – 1 выполнять
{ i := i + 1;
считать из входного файла три числа a, b
и с (каждое по 1 байту);
Т[i].символ := a;
T[i].левый := b;
T[i].правый := c;
}
Декодирование:
i:= 0; //—счетчик символов выходного файла
j:= 2*N–1;//—текущее положение в дереве Хаффмана
считать из входного файла в переменную b
очередной байт;
k := 0; // — номер текущего бита в b
пока i < L выполнять
{ если k = 8 то
{ считать из входного файла в переменную b
очередной байт;
k := 0;
}
c:= getbit(b, k);
k := k + 1;
если с = 0
то j := T[j].левый
иначе j := T[j].правый;
если j £ N то
{ записать в выходной файл T[j].символ;
j := 2*N – 1
}
}
Язык реализации – Си.
Приведем реализацию функции getbit на Си.
int getbit (unsigned char b, int i)
{
return ((b >> (8–i)) & 1);
}
1. В.А.Цикоза, Т.Г.Чурина. Методическое пособие к курсу “Методы программирования” (часть первая). Новосибирск: ВКИ НГУ, 1999.
2. Вирт Н. Алгоритмы и структуры данных. М.: Мир, 1989.–360с.
3. А.Ахо, Д.Хопкрофт, Д. Ульман. Структуры данных и алгоритмы. М.: Издательский дом “Вильямс”, 2000 – 384 с..
4. Хэзфилд Р., Кирби Л. Искусство программирования на C: Фундаментальные алгоритмы, структуры данных и примеры приложений (пер. с англ.) {Энциклопедия программиста} К: ДиаСофт`01- 736 с.
Содержание
Лабораторная работа № 1. Треугольник Паскаля 3
Лабораторная работа № 2. Простые числа 5
Лабораторная работа № 3. Библиотека 6
Лабораторная работа № 4. Системы счисления 8
Лабораторная работа № 5. Перестановки 10
Лабораторная работа № 6. Поиск подстроки в строке 10
Лабораторная работа № 7. Простые сортировки 10
Лабораторная работа № 8. Улучшенные сортировки 10
Лабораторная работа № 9. Сортировка файлов 10
Лабораторная работа № 10. Определение частоты встречаемости символов в файле 10
Лабораторная работа № 11. Построение кода Хаффмана 10
Лабораторная работа № 12. Архивирование 10
Лабораторная работа № 13*.Декодирование 10
Литература 10
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.