Waňov web

PB161 Jazyk C++ - 6. cvicení

Bentleyho kódování

Úvod:

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 DEN
Slovník: KAZDY STUDENT BDI DEN CELY
Zakó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.

Zadání:

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.

Pozadavky:

Poznámky:


Riešenie:


bentley.C
#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;		 
}



Nahor