Bentleyho kódování je slovníková komprese, která je velice úcinná u bezného textu s castým opakováním stejných slov. Prestoze je tento algoritmus velice jednoduchý, pro potrebu naseho príkladu ho trochu upravíme. Toto kódování se dá predvést napríklad na následujícím príklade:
Puvodní zpráva: KAZDY STUDENT BDI KAZDY DEN CELY DENSlovník:
KAZDY STUDENT BDI DEN CELYZakódovaná zpráva:
1 KAZDY 2 STUDENT 3 BDI 1 4 DEN 5 CELY 4
Jak lze videt, algoritmus pridá do slovníku kazdé dosud neznámé slovo. Na výstup
se pak posílá "index slova ve slovníku [bílé místo] slovo samotné"
(v prípade ze dané slovo se vyskytlo poprvé), nebo pouze "index slova "
(v prípade ze slovo jiz ve slovníku existovalo). Index je rostoucí, pocínaje
jednickou, a zvysující se vzdy o 1. Ve skutecnosti se samozrejme slovník
optimalizuje tak, ze slova s nejcastejsím výskytem mají nejnizsí indexy, a
slova s nejméne castým výskytem indexy nejvyssí. My si vsak pro jednoduchost
zavedeme pravidlo, ze se do slovníku budou slova pridávat dle jejich prvního
výskytu (tudíz presne jak v ukázkovém príklade), nikoliv dle cetnosti jejich
výskytu.
Dekódování textu probíhá samozrejme presne opacným zpusobem. Program jako
první prvek na vstupu ocekává císlici 1, následovanou prvním slovem
pridávaným do slovníku. Dále vzdy dvojici "nový_index
bílý_znak nové_ slovo", nebo jen "existující_ index". Na výstup se posílá
dekódovaný text.
Vytvorte program, který bude ze standardního vstupu císt text, a na standardní výstup bude posílat text zakódovaný zjednoduseným Bentleyho kódováním, a opacne.
bentley.
bentley,
bude program kódovat (komprimovat) text na standardním vstupu, a posílat jej na
standardní výstup. Pri pustení programu s volbou -d, tudíz
príkazem bentley -d, bude program dekódovat (dekomprimovat)
text na standardním vstupu, a posílat jej na standarní výstup. Výstup programu
se bude rídit algoritmem popsaným v Úvodu. Pokud bude program spusten s
nesprávnými volbami ci parametry, vypiste na standardní výstup správné pouzití
programu a skoncete.
Prvni text, druhy text, treti text.1 Prvni 2 text, 3 druhy 2 4 treti 5 text.
cout, ale do
cerr. Jinak se stává soucástí zakódovaného textu.
long int.cerr<< (místo cout<<).
cin.get() (0 az 3 parametry (kam, délka, koncový_znak)) - dovolí
Vám nacíst jeden znak ze vstupního bufferucin.unget()
- vrátí poslední prectený znak zpet do vstupního bufferu
long int.
vector nebo asociativní pole map.
int,
prázdný retezec pro string).
>> vrací opet
vstupní proud (levý operand) a ten se pri pouzití na míste logického výrazu
(napr. v podmínce) transformuje na true. Pri pokusu o ctení více
dat, nez soubor obsahuje, vsak >> vrátí hodnotu, jez se
transformuje na false.
#include<iostream>
#include<string>
#include<map>
using namespace std;
long int index=1;
string retazec;
//==================KOMPRIMOVAT=================================================
void komprimovat(void)
{
map<string,int> kompresia;
map<string,int>::iterator p;
for(;;) // hlavny cyklus kompresie
{
if (!(cin>>retazec)) break;
p=kompresia.find(retazec);
if (p==kompresia.end()) // retazec este nepozna
{
kompresia.insert(make_pair(retazec,index));
cout<<index<<' '<<retazec<<' ';
index++;
}
else // retazec uz pozna
{
cout<<p->second<<' ';
}
}
}
//==================DEKOMPRIMOVAT===============================================
void dekomprimovat(void)
{
map<int,string> dekompresia;
map<int,string>::iterator p;
for(;;) // hlavny cyklus dekompresie
{
if (!(cin>>index)) break;
p=dekompresia.find(index);
if (p==dekompresia.end()) // retazec este nepozna
{
cin>>retazec;
dekompresia.insert(make_pair(index,retazec));
cout<<retazec<<' ';
}
else // retazec uz pozna
{
cout<<p->second<<' ';
}
}
}
//==================MAIN========================================================
int main(int argc,char *argv[])
{
if(argc==2)
{
if (argv[1][0]=='-' && argv[1][1]=='d') dekomprimovat();
else{cout<<"Zadali ste nespravny parameter!!\n";
cout<<"Spravny tvar pre dekomprimaciu je: bentley -d\n";
cout<<" pre komprimaciu bez parametra\n";
}
}
else komprimovat();
cout<<endl;
return 0;
}