Студопедия

КАТЕГОРИИ:


Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748)

Метод Хаффмана

Этот алгоритм кодирования информации был предложен Д.А. Хаффманом в 1952 году. Хаффмановское кодирование (сжатие) – это широко используемый метод сжатия, присваивающий символам алфавита коды переменной длины основываясь на вероятностях появления этих символов.

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

Префиксный код – это код, в котором никакое кодовое слово не является префиксом любого другого кодового слова. Эти коды имеют переменную длину.

Оптимальный префиксный код – это префиксный код, имеющий минимальную среднюю длину.

Алгоритм Хаффмана можно разделить на два этапа.

1) Определение вероятности появления символов в исходном тексте.

Первоначально необходимо прочитать исходный текст полностью и подсчитать вероятности появления символов в нем (иногда подсчитывают, сколько раз встречается каждый символ). Если при этом учитываются все 256 символов, то не будет разницы в сжатии текстового или файла иного формата.

2) Нахождение оптимального префиксного кода.

Далее находятся два символа a и b с наименьшими вероятностями появления и заменяются одним фиктивным символом x, который имеет вероятность появления, равную сумме вероятностей появления символов a и b. Затем, используя эту процедуру рекурсивно, находится оптимальный префиксный код для меньшего множества символов (где символы a и b заменены одним символом x). Код для исходного множества символов получается из кодов замещающих символов путем добавления 0 или 1 перед кодом замещающего символа, и эти два новых кода принимаются как коды заменяемых символов. Например, код символа a будет соответствовать коду x с добавленным нулем перед этим кодом, а для символа b перед кодом символа x будет добавлена единица.

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

 

Пример 1. Программная реализация метода Хаффмана.

#include "stdafx.h"

#include <iostream>

using namespace std;

 

void Expectancy();

long MinK();

void SumUp();

void BuildBits();

void OutputResult(char **Result);

void Clear();

 

const int MaxK = 1000;

long k[MaxK + 1], a[MaxK + 1], b[MaxK + 1];

char bits[MaxK + 1][40];

char sk[MaxK + 1];

bool Free[MaxK + 1];

char *res[256];

long i, j, n, m, kj, kk1, kk2;

char str[256];

 

int _tmain(int argc, _TCHAR* argv[]){

char *BinaryCode;

Clear();

cout << "Введите строку для кодирования: ";

cin >> str;

Expectancy();

SumUp();

BuildBits();

OutputResult(&BinaryCode);

cout << "Закодированная строка: " << endl;

cout << BinaryCode << endl;

system("pause");

return 0;

}

//описание функции обнуления данных в массивах

void Clear(){

for (i = 0; i < MaxK + 1; i++){

k[i] = a[i] = b[i] = 0;

sk[i] = 0;

Free[i] = true;

for (j = 0; j < 40; j++)

bits[i][j] = 0;

}

}

/*описание функции вычисления вероятности вхождения каждого символа в тексте*/

void Expectancy(){

long *s = new long[256];

for (i = 0; i < 256; i++)

s[i] = 0;

for (n = 0; n < strlen(str); n++)

s[str[n]]++;

j = 0;

for (i = 0; i < 256; i++)

if (s[i]!= 0){

j++;

k[j] = s[i];

sk[j] = i;

}

kj = j;

}

/*описание функции нахождения минимальной частоты символа в исходном тексте*/

long MinK(){

long min;

i = 1;

while (!Free[i] && i < MaxK) i++;

min = k[i];

m = i;

for (i = m + 1; i <= kk2; i++)

if (Free[i] && k[i] < min){

min = k[i];

m = i;

}

Free[m] = false;

return min;

}

//описание функции подсчета суммарной частоты символов

void SumUp(){

long s1, s2, m1, m2;

for (i = 1; i <= kj; i++){

Free[i] = true;

a[i] = 0;

b[i] = 0;

}

kk1 = kk2 = kj;

while (kk1 > 2){

s1 = MinK();

m1 = m;

s2 = MinK();

m2 = m;

kk2++;

k[kk2] = s1 + s2;

a[kk2] = m1;

b[kk2] = m2;

Free[kk2] = true;

kk1--;

}

}

//описание функции формирования префиксных кодов

void BuildBits(){

strcpy(bits[kk2],"1");

Free[kk2] = false;

strcpy(bits[a[kk2]],bits[kk2]);

strcat(bits[a[kk2]], "0");

strcpy(bits[b[kk2]],bits[kk2]);

strcat(bits[b[kk2]], "1");

i = MinK();

strcpy(bits[m],"0");

Free[m] = true;

strcpy(bits[a[m]],bits[m]);

strcat(bits[a[m]], "0");

strcpy(bits[b[m]],bits[m]);

strcat(bits[b[m]], "1");

for (i = kk2 - 1; i > 0; i--)

if (!Free[i]) {

strcpy(bits[a[i]],bits[i]);

strcat(bits[a[i]], "0");

strcpy(bits[b[i]],bits[i]);

strcat(bits[b[i]], "1");

}

}

//описание функции вывода данных

void OutputResult(char **Result){

(*Result) = new char[1000];

for (int t = 0; i < 1000;i++)

(*Result)[t] = 0;

for (i = 1; i <= kj; i++)

res[sk[i]] = bits[i];

for (i = 0; i < strlen(str); i++)

strcat((*Result), res[str[i]]);

}

Алгоритм Хаффмана универсальный, его можно применять для сжатия данных любых типов, но он малоэффективен для файлов маленьких размеров (за счет необходимости сохранения словаря). В настоящее время данный метод практически не применяется в чистом виде, обычно используется как один из этапов сжатия в более сложных схемах. Это единственный алгоритм, который не увеличивает размер исходных данных в худшем случае (если не считать необходимости хранить таблицу перекодировки вместе с файлом).

 

<== предыдущая лекция | следующая лекция ==>
Текст лекции. Лекция 41 Алгоритмы сжатия данных | Кодовые деревья
Поделиться с друзьями:


Дата добавления: 2014-01-04; Просмотров: 671; Нарушение авторских прав?; Мы поможем в написании вашей работы!


Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет



studopedia.su - Студопедия (2013 - 2024) год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! Последнее добавление




Генерация страницы за: 0.025 сек.