Si të konfiguroni telefonat inteligjentë dhe PC. Portali informativ

Shembuj të kodimit Rle. Mosekzistenca e një algoritmi ideal

Duke përdorur algoritmin RLE, kodoni sekuencën e karaktereve BBBBBBACCCABBBBBBB

Shkruani rezultatin si kode heksadecimal (çdo karakter është i koduar si një bajt, i cili përfaqësohet nga dy shifra heksadecimal). Kontrolloni rezultatin duke përdorur programin RLE.

Dekodoni sekuencën e paketuar duke përdorur algoritmin RLE (janë dhënë kodet heksadecimal): 01 4D 8E 41 01 4D 8E 4116. Përdorni tabelën ASCII për të përcaktuar karakteret sipas kodit të tyre heksadecimal. Në tabelën e mësipërme, rreshti i parë përmban shifrën e parë të kodit të karakterit heksadecimal dhe rreshti i dytë përmban të dytin. Për shembull, karakteri "&" ka kodin heksadecimal 2616.

Përcaktoni numrin e bajteve në sekuencën origjinale dhe të dekompresuar dhe llogaritni raportin e kompresimit: Kontrolloni rezultatin e marrë në paragrafi i mëparshëm, duke përdorur programin RLE. Sugjeroni dy mënyra për të kontrolluar. Ndërtoni sekuenca që kompresohen nga algoritmi RLE saktësisht 2 herë, 4 herë, 5 herë. Kontrolloni përgjigjet tuaja me programin RLE. Mendoni për tre sekuenca që nuk mund të kompresohen duke përdorur algoritmin RLE: Duke përdorur programin RLE, aplikoni kompresimin RLE në skedarët e mëposhtëm dhe gjeni raportin e kompresimit për secilin prej tyre: Shpjegoni rezultatet e marra në paragrafin e mëparshëm:
    Pse nuk mund të kompresoj fotot në Formati JPEG? pse për dy vizatime në Formati BMP raportet e njëjta të ngjeshjes sipas madhësisë sipas algoritmit RLE janë kaq të ndryshme? Këshillë: hapni këto vizatime në çdo shikues.
Vlerësoni raportin maksimal të arritshëm të kompresimit duke përdorur variantin e tekstit shkollor të algoritmit RLE. Në cilin rast mund të arrihet?
Vlerësoni raportin e kompresimit duke përdorur algoritmin RLE në rastin më të keq. Përshkruani këtë rast më të keq.

  • tutorial

Shumë kohë më parë, kur isha ende një nxënës naiv i shkollës, papritmas u bëra tmerrësisht kurioz: si me magji zënë më pak hapësirë ​​të dhënat në arkiva? Duke hipur në telefonin tim besnik, fillova të shfletoj në internet në kërkim të një përgjigjeje dhe gjeta shumë artikuj me një prezantim mjaft të detajuar të informacionit që më interesonte. Por asnjëra prej tyre nuk dukej e lehtë për t'u kuptuar atëherë - listat e kodeve dukeshin si shkronja kineze dhe përpjekjet për të kuptuar terminologjinë e pazakontë dhe formulat e ndryshme ishin të pasuksesshme.

Prandaj, qëllimi i këtij artikulli është të japë një ide të algoritmeve më të thjeshta të kompresimit për ata, njohuritë dhe përvoja e të cilëve ende nuk i lejojnë ata të kuptojnë menjëherë më shumë literaturë profesionale, ose profili i të cilëve është plotësisht larg temave të tilla. ato. Unë do të flas "në gishta" për disa nga algoritmet më të thjeshta dhe do të jap shembuj të zbatimit të tyre pa lista të kodeve kilometërshe.

Unë do t'ju paralajmëroj menjëherë se nuk do të marr parasysh detajet e zbatimit të procesit të kodimit dhe nuanca të tilla si kërkimi efikas i dukurive të një vargu. Artikulli do të prekë vetëm vetë algoritmet dhe mënyrat e paraqitjes së rezultatit të punës së tyre.

RLE - Kompaktësia e Uniformitetit

Algoritmi RLEështë ndoshta më e thjeshta nga të gjitha: thelbi i saj qëndron në kodimin e përsëritjeve. Me fjalë të tjera, ne marrim sekuenca të elementeve identike dhe i "kolapsojmë" ato në çifte numërimi/vlera. Për shembull, një varg si "AAAAAAAABCCCC" mund të konvertohet në një hyrje si "8xA, B, 4xC". Kjo është, në përgjithësi, gjithçka që duhet të dini për algoritmin.

Shembull zbatimi

Supozoni se kemi një grup koeficientësh të plotë që mund të marrin vlera nga 0 në 255. Logjikisht, arritëm në përfundimin se është e arsyeshme ta ruajmë këtë grup si një grup bajtësh:
të dhëna karakteresh të panënshkruara = ( 0, 0, 0, 0, 0, 0, 4, 2, 0, 4, 4, 4, 4, 4, 4, 4, 80, 80, 80, 80, 0, 2, 2 , 2, 2, 255, 255, 255, 255, 255, 0, 0);

Për shumë njerëz, do të jetë shumë më e njohur për t'i parë këto të dhëna si një hale hex:
0000: 00 00 00 00 00 00 04 02 00 04 04 04 04 04 04 04
0010: 50 50 50 50 00 02 02 02 02 FF FF FF FF 00 00

Me reflektim, vendosëm që do të ishte mirë të ngjeshim disi grupe të tilla për të kursyer hapësirë. Për ta bërë këtë, ne i analizuam ato dhe identifikuam një model: shumë shpesh ka nënsekuenca që përbëhen nga të njëjtat elementë. Sigurisht, RLE është e përkryer për këtë!

Le të kodojmë të dhënat tona duke përdorur njohuritë e marra rishtazi: 6x0, 4, 2, 0, 7x4, 4x80, 0, 4x2, 5x255, 2x0.

Është koha që disi të paraqesim rezultatin tonë në një formë miqësore me kompjuterin. Për ta bërë këtë, në rrjedhën e të dhënave, ne duhet të ndajmë disi bajt të vetëm nga vargjet e koduara. Meqenëse i gjithë diapazoni i vlerave të bajtit përdoret nga të dhënat tona, nuk do të jetë e mundur që thjesht të shpërndajmë ndonjë varg vlerash për qëllimet tona.

Ekzistojnë të paktën dy mënyra për të dalë nga kjo situatë:

  1. Si tregues i një zinxhiri të ngjeshur, zgjidhni një vlerë bajt dhe në rast përplasjeje me të dhëna reale, shmangni ato. Për shembull, nëse përdorim vlerën 255 për qëllime "zyrtare", atëherë kur kjo vlerë të ndeshet në të dhënat hyrëse, do të duhet të shkruajmë "255, 255" dhe të përdorim një maksimum prej 254 pas treguesit.
  2. Strukturoni të dhënat e koduara, duke treguar numrin e elementeve të vetëm jo vetëm të përsëritur, por edhe pasues. Atëherë do të dimë paraprakisht se ku janë të dhënat.
Metoda e parë në rastin tonë nuk duket efektive, kështu që, ndoshta, do t'i drejtohemi të dytës.

Pra, tani kemi dy lloje sekuencash: vargjet e elementeve të vetme (si "4, 2, 0") dhe vargjet e elementeve identike (si "0, 0, 0, 0, 0, 0"). Le të ndajmë një bit në bajtet e "shërbimit" për llojin e sekuencës: 0 - elemente të vetme, 1 - identike. Merrni për këtë, le të themi, pakën më domethënëse të një bajt.

Në 7 bitet e mbetura, do të ruajmë gjatësitë e sekuencave, d.m.th. gjatësia maksimale e sekuencës së koduar është 127 bajt. Ne mund të ndajmë, të themi, dy bajt për qëllime shërbimi, por në rastin tonë sekuenca të tilla të gjata janë jashtëzakonisht të rralla, kështu që është më e lehtë dhe më ekonomike t'i ndajmë ato në më të shkurtra.

Rezulton se në rrjedhën e daljes së pari do të shkruajmë gjatësinë e sekuencës, dhe më pas ose një vlerë të përsëritur, ose një zinxhir elementësh jo-përsëritës të gjatësisë së specifikuar.

Gjëja e parë që duhet t'ju bie në sy është se në këtë situatë kemi disa vlera të papërdorura. Nuk mund të ketë sekuenca me gjatësi zero, kështu që ne mund të rritemi gjatësia maksimale deri në 128 bajt, duke zbritur një nga gjatësia gjatë kodimit dhe duke shtuar kur deshifroni. Pra, ne mund të kodojmë gjatësitë nga 1 në 128 në vend të gjatësive nga 0 në 127.

Gjëja e dytë që duhet theksuar është se nuk ka sekuenca të elementeve identike me gjatësi njësi. Prandaj, kur kodojmë, do të zbresim një më shumë nga gjatësia e sekuencave të tilla, duke rritur kështu gjatësinë e tyre maksimale në 129 (gjatësia maksimale e një zinxhiri elementësh të vetëm është ende 128). ato. Zinxhirët e elementëve identikë mund të kenë një gjatësi nga 2 në 129.

Le të kodojmë përsëri të dhënat tona, por tani në një formë të kuptueshme për kompjuterin. Ne do t'i shkruajmë bajtët e shërbimit si , ku T është lloji i sekuencës dhe L është gjatësia. Menjëherë do të kemi parasysh që gjatësitë i shkruajmë në formë të modifikuar: në T=0 zbresim një nga L, në T=1 - dy.

0, , 4, 2, 0, , 4, , 80, , 0, , 2, , 255, , 0

Le të përpiqemi të deshifrojmë rezultatin tonë:

  • . T=1, atëherë bajti tjetër do të përsëritet L+2 (4+2) herë: 0, 0, 0, 0, 0, 0.
  • . T=0, kështu që thjesht lexoni L+1 (2+1) bajt: 4, 2, 0.
  • . T=1, përsëritni bajtin tjetër 5+2 herë: 4, 4, 4, 4, 4, 4, 4.
  • . T=1, përsërisni bajtin tjetër 2+2 herë: 80, 80, 80, 80.
  • . T=0, lexo 0+1 bajt: 0.
  • . T=1, përsëriteni bajtin 2+2 herë: 2, 2, 2, 2.
  • . T=1, përsëritni bajt 3+2 herë: 255, 255, 255, 255, 255.
  • . T=1, përsëriteni bajt 0+2 herë: 0, 0.

Dhe tani hapi i fundit: ruajeni rezultatin si një grup bajtësh. Për shembull, një çift i paketuar në një bajt do të duket kështu:

Si rezultat, marrim sa vijon:
0000: 84 00 02 04 02 00 85 04 82 80 00 00 82 02 83 FF
0010: 80 00

Në një mënyrë kaq të thjeshtë, ky shembull Nga të dhënat hyrëse, morëm 18 nga 32 bajt. Jo një rezultat i keq, veçanërisht duke pasur parasysh se mund të jetë shumë më i mirë në zinxhirë më të gjatë.

Përmirësime të mundshme

Efikasiteti i një algoritmi varet jo vetëm nga vetë algoritmi, por edhe nga mënyra se si zbatohet. Prandaj, për të dhëna të ndryshme është e mundur të zhvillohen variacione të ndryshme të kodimit dhe paraqitjes së të dhënave të koduara. Për shembull, kur kodoni imazhe, mund të krijoni zinxhirë me gjatësi të ndryshueshme: ndani një bit për të treguar një zinxhir të gjatë dhe nëse është vendosur në një, atëherë ruani gjatësinë edhe në bajtin tjetër. Kështu sakrifikojmë gjatësinë e zinxhirëve të shkurtër (65 elementë në vend të 129), por nga ana tjetër, bëjmë të mundur kodimin e zinxhirëve deri në 16385 elementë të gjatë (2 14 + 2) me vetëm tre bajt!

Efikasitet shtesë mund të arrihet duke përdorur teknikat e kodimit heuristik. Për shembull, le të kodojmë zinxhirin e mëposhtëm në mënyrën tonë: "ABBA". Marrim " , A, , B, , A" - d.m.th. Kemi kthyer 4 bajt në 6, kemi fryrë të dhënat origjinale sa një herë e gjysmë! Dhe sa më shumë sekuenca të tilla të shkurtra heterogjene të alternuara, aq më shumë të dhëna të tepërta. Nëse e marrim këtë parasysh, atëherë mund të kodojmë rezultatin si ", A, B, B, A" - do të shpenzonim vetëm një bajt shtesë.

LZ77 - shkurtësi në përsëritje

LZ77 është një nga algoritmet më të thjeshtë dhe më të njohur në familjen LZ. I quajtur sipas krijuesve të tij: Abraham Lempel (Abraham L empel) dhe Jacob Ziv (Jacob Z iv). Numrat 77 në titull nënkuptojnë vitin 1977, në të cilin u botua një artikull që përshkruan këtë algoritëm.

Ideja kryesore është që të kodohen sekuenca identike të elementeve. Kjo do të thotë, nëse një zinxhir elementësh ndodh më shumë se një herë në të dhënat hyrëse, atëherë të gjitha shfaqjet e tij të mëvonshme mund të zëvendësohen me "lidhje" në instancën e tij të parë.

Ashtu si pjesa tjetër e algoritmeve të kësaj familjeje të familjes, LZ77 përdor një fjalor që ruan sekuencat e hasura më parë. Për ta bërë këtë, ai zbaton parimin e të ashtuquajturit. " dritare rrëshqitëse': zona gjithmonë përpara pozicionit aktual të kodimit brenda së cilës mund të adresojmë lidhjet. Kjo dritare është fjalori dinamik për këtë algoritëm- çdo element në të korrespondon me dy atribute: pozicioni në dritare dhe gjatësia. Edhe pse në kuptimin fizik, kjo është vetëm një pjesë e kujtesës që ne e kemi koduar tashmë.

Shembull zbatimi

Le të përpiqemi të kodojmë diçka tani. Le të krijojmë një varg të përshtatshëm për këtë (kërkoj falje paraprakisht për absurditetin e tij):

"Ngjeshja dhe dekompresimi lë një përshtypje. Hahahahaha!"

Ja se si do të duket në memorie (enkodimi ANSI):
0000: 54 68 65 20 63 6F 6D 70 72 65 73 73 69 6F 6E 20 Kompresimi
0010: 61 6E 64 20 74 68 65 20 64 65 63 6F 6D 70 72 65 dhe dekompresoni
0020: 73 73 69 6F 6E 20 6C 65 61 76 65 20 61 6E 20 69 ssion lë një i
0030: 6D 70 72 65 73 73 69 6F 6E 2E 20 48 61 68 61 68 Hahah
0040: 61 68 61 68 61 21 ahaha!

Ne nuk kemi vendosur ende për madhësinë e dritares, por do të biem dakord që ajo mbi madhësinë varg i koduar. Le të përpiqemi të gjejmë të gjitha vargjet përsëritëse të karaktereve. Një varg është një sekuencë karakteresh më të gjata se një. Nëse zinxhiri është pjesë e një zinxhiri më të gjatë përsëritës, ne do ta injorojmë atë.

“Ngjeshja dhe lënia[an] i . Hah!”

Për qartësi më të madhe, le të shohim diagramin, ku mund të shohim korrespondencën e sekuencave të përsëritura dhe shfaqjet e tyre të para:

Ndoshta e vetmja pikë e paqartë këtu është sekuenca "Hahahahaha!", sepse vargu i karaktereve "ahahaha" korrespondon me vargun e shkurtër "ah". Por nuk ka asgjë të pazakontë këtu, ne kemi përdorur një truk që lejon algoritmin ndonjëherë të funksionojë si RLE i përshkruar më parë.

Fakti është se kur shpaketojmë, do të lexojmë numrin e specifikuar të karaktereve nga fjalori. Dhe meqenëse e gjithë sekuenca është periodike, d.m.th. të dhënat në të përsëriten me një periudhë të caktuar, dhe simbolet e periudhës së parë do të jenë pikërisht përpara pozicionit të shpaketimit, atëherë ne mund të rikrijojmë të gjithë zinxhirin prej tyre, thjesht duke kopjuar simbolet e periudhës së mëparshme në tjetrën.

U rregullua. Tani le të zëvendësojmë përsëritjet e gjetura me referenca në fjalor. Ne do ta shkruajmë lidhjen në formatin , ku P është pozicioni i shfaqjes së parë të vargut në varg, L është gjatësia e tij.

“Ngjeshja dhe t de largimi i . Hah!”

Por mos harroni se kemi të bëjmë me një dritare rrëshqitëse. Për të kuptuar më mirë, në mënyrë që lidhjet të mos varen nga madhësia e dritares, ne do të zëvendësojmë pozicionet absolute me diferencën midis tyre dhe pozicionit aktual të kodimit.

“Ngjeshja dhe t de largimi i . Hah!”

Tani na duhet vetëm të zbresim P nga pozicioni aktual i kodimit për të marrë pozicionin absolut në varg.

Është koha për të vendosur për madhësinë e dritares dhe gjatësinë maksimale të frazës së koduar. Meqenëse kemi të bëjmë me tekst, është e rrallë që në të të ketë sekuenca të përsëritura veçanërisht të gjata. Pra, le të ndajmë, të themi, 4 bit për gjatësinë e tyre - një kufi prej 15 karaktere në një kohë është mjaft i mjaftueshëm për ne.

Por madhësia e dritares tashmë varet nga sa thellë do të kërkojmë të njëjtat zinxhirë. Meqenëse kemi të bëjmë me tekste të vogla, do të jetë e drejtë të plotësojmë numrin e biteve që përdorim në dy bajt: do të adresojmë lidhje në një gamë prej 4096 bajte, duke përdorur 12 bit për këtë.

Ne e dimë nga përvoja me RLE se jo të gjitha vlerat mund të përdoren. Natyrisht, lidhja mund të ketë një vlerë minimale prej 1, prandaj, për të adresuar përsëri në intervalin 1..4096, duhet të zbresim një nga lidhja kur kodojmë dhe të shtojmë përsëri kur deshifrojmë. E njëjta gjë me gjatësitë e sekuencave: në vend të 0..15 do të përdorim diapazonin 2..17, pasi nuk punojmë me gjatësi zero dhe karakteret individuale nuk janë sekuenca.

Pra, le të imagjinojmë tekstin tonë të koduar, duke marrë parasysh këto ndryshime:

“Ngjeshja dhe t de largimi i . Hah!”

Tani, përsëri, ne duhet të ndajmë disi zinxhirët e ngjeshur nga pjesa tjetër e të dhënave. Mënyra më e zakonshme është të përdoret përsëri struktura dhe të tregohet drejtpërdrejt se ku janë të ngjeshura të dhënat dhe ku jo. Për ta bërë këtë, ne do t'i ndajmë të dhënat e koduara në grupe me tetë elementë (karaktere ose lidhje), dhe para secilit prej këtyre grupeve do të fusim një bajt, ku çdo bit korrespondon me llojin e elementit: 0 për një karakter dhe 1 për një lidhje.

Ndahemi në grupe:

  • "Kompjuteri"
  • "falje"
  • "dhe t de"
  • "largohu"
  • "i. hah"
Përpilimi i grupeve:

"(0,0,0,0,0,0,0,0) Rezsioni komp(0,0,0,0,0,0,0,0) (0,0,0,0,0,1 ,0,0) dhe t de(1,0,0,0,0,0,1,0) largohen (0,1,0,0,0,0,0,1) i . Hah (0)!"

Kështu, nëse hasim bitin 0 gjatë zbërthimit, atëherë thjesht lexojmë karakterin në rrjedhën e daljes, nëse biti është 1, lexojmë lidhjen dhe me referencë lexojmë sekuencën nga fjalori.

Tani ne vetëm duhet të grupojmë rezultatin në një grup bajtësh. Le të biem dakord që ne përdorim bit dhe bajt në rend nga lart në të ulët. Le të shohim se si lidhjet paketohen në bajt duke përdorur një shembull:

Si rezultat, rrjedha jonë e ngjeshur do të duket kështu:

0000:00 54 68 65 20 63 6f 6d 70 00 72 65 73 73 69 6f #The Comp#ressio
0010: 6e 20 04 61 6e 64 20 74 01 31 64 65 82 01 5a 6c n #dhe t##de###l
0020: 65 61 76 65 01 b1 20 41 69 02 97 2e 20 48 61 68 eave## #i##. Hah
0030: 00 15 00 21 00 00 00 00 00 00 00 00 00 00 00 00 ###!

Përmirësime të mundshme

Në parim, gjithçka që u përshkrua për RLE do të jetë e vërtetë këtu. Në veçanti, për të demonstruar dobinë e qasjes heuristike në kodim, merrni parasysh shembullin e mëposhtëm:

“E gjatë goooooong. Lidhur më shumë."

Le të gjejmë sekuenca vetëm për fjalën "looooooower":

"E gjata goooooong. Të lidhur.”

Për të koduar një rezultat të tillë, na duhen katër bajt për lidhje. Sidoqoftë, do të ishte më ekonomike ta bëni këtë:

"E gjata goooooong. Unë isha i lidhur."

Atëherë do të shpenzonim një bajt më pak.

Në vend të një përfundimi

Megjithë thjeshtësinë e tyre dhe, siç duket, efikasitetin jo shumë të madh, këto algoritme ende përdoren gjerësisht në fusha të ndryshme të sferës së IT.

Avantazhi i tyre është thjeshtësia dhe shpejtësia, dhe algoritme më komplekse dhe efikase mund të bazohen në parimet dhe kombinimet e tyre.

Shpresoj që thelbi i këtyre algoritmeve të deklaruara në këtë mënyrë do të ndihmojë dikë të kuptojë bazat dhe të fillojë të shikojë drejt gjërave më serioze.

Edhe 10-15 vjet më parë, arkivuesit përdoreshin kryesisht për të kursyer hapësirë ​​në hard disk dhe për të vendosur sa më shumë të dhëna në një disketë. Megjithatë, kohët kanë ndryshuar. Askush nuk ka përdorur disqe si një mjet për transferimin dhe ruajtjen e informacionit për një kohë të gjatë, dhe kostoja e disqeve është bërë aq e ulët sa askush nuk mendon as të kompresojë të dhënat për të kursyer hapësirë. Përveç kësaj, vëllimet e të dhënave janë bërë aq të mëdha sa që arkivimi dhe heqja e tyre për të kursyer hapësirë ​​thjesht nuk është praktike, sepse kërkon shumë kohë. Epo, me të vërtetë, sot sasia e të dhënave në disqet e përdoruesve matet në terabajt. Tani imagjinoni se sa kohë do të duhet për të arkivuar një terabajt të dhënash. Kjo do të zgjasë jo një apo edhe dy orë, por të paktën 10-12 orë, domethënë kompjuteri do të duhet të lihet i ndezur gjithë natën.

Duket se arkivuesit sot duhet të humbasin gradualisht rëndësinë e tyre. Por asgjë e tillë nuk ndodh. Shumica dërrmuese e përdoruesve, midis programeve të tjera, kanë arkivues të instaluar, ose përdorin një arkivues të integruar në sistemin operativ Windows (ne nuk i konsiderojmë sistemet e tjera operative në këtë botim).

Fakti është se emërimi i arkivorëve ka ndryshuar. Sot ato përdoren kryesisht për postimin e të dhënave në ueb. Shumica e drejtuesve në faqet e internetit të prodhuesve janë të vendosura në arkiva, dhe shumica e programeve në burime të ndryshme janë gjithashtu të arkivuara. Nga rruga, vetë përdoruesi, përpara se të ngarkojë ndonjë të dhënë në Rrjet (për shembull, në burimet e ndarjes së skedarëve), i paketon të dhënat në një arkiv.

në lidhje me tregu rus, atëherë kemi tre arkivuesit më të zakonshëm: WinRAR, WinZip dhe 7-Zip, të paraqitur në të dy versionet 32-bit dhe 64-bit. Janë ata që ne do t'i krahasojmë në këtë artikull. Megjithatë, së pari, le të hedhim një vështrim të shpejtë në disa aspektet teorike punë arkivimi.

Algoritmet e kompresimit të informacionit

Thelbi i çdo algoritmi të kompresimit të informacionit është të përftohet, me një transformim të caktuar të grupit fillestar të biteve të informacionit, në dalje një grup të caktuar. më të vogla. Për më tepër, të gjitha algoritmet e transformimit të të dhënave mund të ndahen me kusht në dy klasa: të kthyeshme dhe të pakthyeshme.

Një algoritëm i pakthyeshëm i kompresimit të informacionit nënkupton një transformim të tillë të sekuencës origjinale të biteve, në të cilën sekuenca dalëse e një madhësie më të vogël nuk lejon që sekuenca e hyrjes të rikthehet saktësisht. Përdoren algoritme të pakthyeshme të kompresimit, për shembull, në lidhje me të dhënat grafike, video dhe audio, dhe kjo çon gjithmonë në një humbje të cilësisë së tyre. Natyrisht, algoritmet për kompresimin e pakthyeshëm të të dhënave nuk përdoren në arkivues, dhe për këtë arsye ne nuk do t'i shqyrtojmë ato më tej.

Algoritmet e kthyeshme të kompresimit të të dhënave ju lejojnë të rivendosni saktësisht sekuencën origjinale të të dhënave nga sekuenca e ngjeshur. Janë këto algoritme që përdoren në arkivues. Karakteristikat e përgjithshme nga të gjitha algoritmet e kompresimit janë raporti i kompresimit (raporti i vëllimeve të sekuencës së të dhënave origjinale dhe të ngjeshur), shkalla e kompresimit (koha e shpenzuar për arkivimin e një sasie të caktuar të dhënash) dhe cilësia e kompresimit (një vlerë që tregon se sa fort është sekuenca e të dhënave kompresohet duke aplikuar rikompresim në të sipas këtij ose ndonjë algoritmi tjetër).

Teoria e kompresimit të informacionit, e njohur edhe si teoria e kodimit ekonomik të informacionit diskret, është një degë mjaft komplekse e shkencës matematikore. Sigurisht, prezantimi edhe i bazave të tij është shumë përtej qëllimit të këtij artikulli, dhe për këtë arsye ne do të shqyrtojmë vetëm sipërfaqësisht algoritme të ndryshme të kompresimit të informacionit pa hyrë në detaje. Për më tepër, sot janë zhvilluar shumë algoritme të kompresimit të të dhënave dhe shqyrtimi i tyre është gjithashtu pjesë e detyrës sonë. Prandaj, ne do të flasim vetëm në një nivel cilësor për disa algoritme që na lejojnë të marrim një ide të përgjithshme të metodave të ngjeshjes së informacionit.

Algoritmi RLE

Një nga metodat më të vjetra dhe më të thjeshta të kompresimit të informacionit është algoritmi RLE (Run Length Encoding), pra algoritmi për kodimin e serive të sekuencave. Kjo metodë është shumë e thjeshtë për t'u zbatuar dhe është një nga algoritmet e arkivimit, dhe thelbi i saj është zëvendësimi i një serie (grupi) bajtësh të përsëritur me një bajt kodues dhe një numërues për numrin e përsëritjeve të tyre. Kjo do të thotë, një grup bajtësh identikë do të zëvendësohet nga një palë:<счетчик повторений, значение>, e cila redukton tepricën e të dhënave.

Në këtë algoritëm, shenja e numëruesit janë ato në dy bitet e sipërme të bajtit të lexuar. Për shembull, nëse dy bitët e parë janë 11, atëherë 6 bitët e mbetur ndahen në numërues, i cili mund të marrë vlera nga 1 në 64. Prandaj, një seri prej 64 bajtësh të përsëritur mund të përcaktohet me vetëm dy bajt, që është, i ngjeshur me 32 herë.

Ekziston një zbatim tjetër i këtij algoritmi, kur shenja e numëruesit është 1 në bajtin e parë të numëruesit. Në këtë rast, numëruesi mund të marrë vlera maksimale, e barabartë me 127 - dhe për këtë arsye raporti maksimal i kompresimit do të jetë i barabartë me 64.

Është e qartë se algoritmi RLE është efikas vetëm kur ka një numër të madh grupesh të gjata bajtash identike. Nëse bajtët nuk përsëriten, atëherë përdorimi i metodës RLE çon në një rritje të madhësisë së skedarit.

Metoda RLE është përgjithësisht shumë efikase për kompresimin e grafikëve bitmap (BMP, PCX, TIF, GIF) sepse ato përmbajnë seri shumë të gjata të sekuencave të bajtit të përsëritur.

Kufizimi i alfabetit të informacionit

Një mënyrë tjetër mjaft e thjeshtë për të kompresuar informacionin mund të quhet kufizim alfabeti informativ. Vëmë re menjëherë se në praktikë një algoritëm i tillë nuk zbatohet, por prezantimi i kësaj metode do të ndihmojë për të kuptuar më mirë metodën e kodeve me gjatësi të ndryshueshme.

Në vijim, me alfabetin informativ do të nënkuptojmë grupin e simboleve të përdorura për të koduar sekuencën informative. Për shembull, supozoni se ka një mesazh me tekst. Çdo shkronjë e këtij mesazhi është e koduar duke përdorur një tabelë ASCII të përbërë nga 256 karaktere. Në këtë rast, saktësisht 8 bit (1 bajt) ndahen për kodimin e çdo karakteri. Në këtë rast, alfabeti i informacionit është të gjitha 256 karakteret e tabelës së kodimit ASCII.

Është e qartë se jo të gjithë 256 karakteret e tabelës ASCII mund të përdoren në mesazhin origjinal me tekst. Për shembull, nëse po flasim për një mesazh me tekst në rusisht që nuk përmban numra, mjaftojnë 64 karaktere (33 shkronja të vogla dhe 31 shkronja të mëdha). Nëse kësaj i shtojmë shenjat e pikësimit, shenjat e paragrafit dhe shenjat e linjës së re, bëhet e qartë se numri i karaktereve nuk do të kalojë 100. Në këtë rast, mund të përdorni kodimin e karaktereve jo 8, por 7-bit, i cili ju lejon të merrni një tabelë me 128 karaktere. Kjo do të thotë, ne, si të thuash, kufizojmë alfabetin informativ, për shkak të të cilit mund të zvogëlojmë thellësinë e bitit të çdo karakteri të renditur. Mund të shkoni më tej - për të përcaktuar me saktësi numrin e karaktereve të përdorura në një mesazh me tekst. Nëse, për shembull, rezulton se në mesazh përdoren vetëm 30 karaktere (përfshirë linjat e reja), atëherë mund të përdoret një tabelë kodimi 5-bit që përmban 32 karaktere, dhe më pas raporti i kompresimit të mesazhit me tekst do të bëhet edhe më i madh. Në të vërtetë, nëse kodimi i karaktereve 8-bit përdoret në mesazhin origjinal, dhe kodimi i karaktereve 5-bit përdoret në mesazhin e ngjeshur, atëherë raporti i kompresimit do të jetë 8/5.

Megjithë thjeshtësinë e dukshme të metodës së kufizimit të alfabetit, në praktikë ajo nuk përdoret. Fakti është se metoda e përshkruar nuk lejon deshifrimin e saktë të mesazhit origjinal pa transmetuar informacion shtese. Në të vërtetë, pa i ditur tabelat e kodimit të përdorura për të kompresuar informacionin, është e pamundur ta deshifrosh atë. Kjo do të thotë, së bashku me sekuencën e informacionit të koduar, është e nevojshme të transmetohen tabelat e kodimit. Është e qartë se në këtë rast fitimi nga përdorimi i një alfabeti të kufizuar reduktohet në zero.

Metoda e alfabetit të kufizuar ka edhe disavantazhe të tjera. Nëse mesazhi origjinal i informacionit përmban një numër të madh karakteresh të ndryshëm, atëherë nuk do të jetë e mundur të zvogëlohet thellësia e bitit të paraqitjes së karaktereve alfabetike dhe kjo metodë thjesht nuk do të funksionojë. Supozoni, për shembull, që mesazhi origjinal i informacionit përmban 129 karaktere nga një alfabet me 256 karaktere. Nuk do të jetë e mundur të përdoret kodimi i karaktereve 7-bit në këtë rast, pasi 7 bit do të kodojnë vetëm 128 karaktere. Prandaj, për 129 karaktere, do të duhet të përdorni të njëjtin kodim 8-bit si në alfabetin origjinal me 256 karaktere.

Kodet me gjatësi të ndryshueshme

Një nga disavantazhet kryesore të metodës hipotetike të kufizimit të alfabetit që kemi shqyrtuar është se ajo përdor një kod uniform kur të gjithë karakteret e alfabetit të informacionit kanë të njëjtën gjatësi (8.7 bit ose më pak). Do të ishte më logjike të përdoret një sistem i tillë kodimi në të cilin gjatësia e kodit të karakterit varet nga frekuenca e shfaqjes së tij në mesazhin e informacionit. Kjo do të thotë, nëse në mesazhin informativ origjinal disa karaktere shfaqen më shpesh se të tjerët, atëherë është optimale që ata të përdorin kode të shkurtra, dhe për ato të rralla, ato më të gjata.

Si një shembull hipotetik, merrni parasysh mesazhin informues të mëposhtëm: "përplasje ajrore" , i cili përmban 14 karaktere. Supozoni se kemi një alfabet prej 14 karakteresh që na lejon të kodojmë këtë mesazh. Nëse përdoret një kod uniform, atëherë kërkohen 4 bit për çdo karakter të alfabetit (gjatësia e kodit prej 4 bitesh do të formojë 16 karaktere). Sidoqoftë, është e lehtë të shihet se në mesazhin tonë informativ simboli "a" shfaqet pesë herë, simboli "t" - dy herë, dhe pjesa tjetër e simboleve - një herë. Nëse për simbolin "a" përdorim një kod prej 2 bitësh, për simbolin "t" - 3 bit, dhe për pjesën tjetër të karaktereve - 4 bit, atëherë sigurisht që mund të kursejmë. Është e nevojshme vetëm të kuptohet se si të ndërtohen saktësisht kodet me gjatësi të ndryshueshme dhe se si saktësisht gjatësia e kodit duhet të varet nga frekuenca e simbolit në mesazhin informativ.

Nëse të gjithë karakteret përfshihen në mesazhin e informacionit me të njëjtën frekuencë (ekuivalente), atëherë me një alfabet informues prej N karakteresh, çdo karakter do të duhet të kodohet saktësisht log 2 N pak. Në fakt, ky është një rast i kodit uniform.

Nëse simbolet kanë probabilitet të ndryshëm për t'u shfaqur në mesazhin informativ, atëherë, sipas teorisë së K. Shannon, simboli, probabiliteti i të cilit është i barabartë me p, është optimal dhe, ajo që është veçanërisht e rëndësishme, teorikisht është e mundur të shoqëroni një kod të gjatësisë -log 2 fq. Duke iu rikthyer shembullit tonë me mesazhin informativ "përplasje ajrore" dhe duke qenë se probabiliteti i shfaqjes së karakterit "a" (p(a)) është 5/14, probabiliteti i shfaqjes së karakterit "t" është 2. /14, dhe probabiliteti i shfaqjes së të gjithë karaktereve të tjera është 1/14, marrim se: për karakterin "a", gjatësia optimale e kodit është -log 2 (5/14) = 1,48 bit; për karakterin "t" - -log 2 (2/14) = 2.8 bit, dhe për të gjithë karakteret e tjera është -log 2 (1/14) = 3.8. Meqenëse në rastin tonë gjatësia e kodit mund të ketë vetëm një vlerë të plotë, atëherë, duke rrumbullakosur lart, marrim se për simbolin "a" është optimale të përdoret një kod prej 2 bitësh, për simbolin "t" - 3 bit, dhe për pjesën tjetër - 4 bit.

Le të llogarisim raportin e kompresimit kur përdorim këtë kodim. Nëse do të përdorej një kod uniform i bazuar në një alfabet me 14 karaktere, atëherë do të kërkoheshin 56 bit për të koduar fjalën "përplasje ajrore". Kur përdorni kode me gjatësi të ndryshueshme, do të kërkohen 5×2 bit + 2×3 bit + 7×4 bit = 44 bit, d.m.th. raporti i kompresimit do të jetë 1.27.

Tani merrni parasysh algoritmet për marrjen e kodeve me gjatësi të ndryshueshme.

kodimi i prefiksit

Shumica metodë e thjeshtë marrja e kodeve me gjatësi të ndryshueshme është i ashtuquajturi kodim prefiks, i cili ju lejon të merrni kode me gjatësi të plotë. tipar kryesor kodet e parashtesave qëndrojnë në faktin se brenda secilit sistem të tyre kodet më të shkurtra nuk përkojnë me fillimin (prefiksin) e kodeve më të gjata. Është kjo veti e kodeve të prefiksit që e bën shumë të lehtë dekodimin e informacionit.

Le ta shpjegojmë këtë veti të kodeve të parashtesave me një shembull specifik. Le të ketë një sistem me tre kode parashtesash: (0, 10, 11). Siç mund ta shihni, kodi më i shkurtër 0 nuk përkon me fillimin e kodeve më të gjata 10 dhe 11. Le të specifikojë kodin 0 karakterin "a", kodin 10 karakterin "m" dhe kodin 11 karakterin "p". Pastaj fjala "kornizë" është e koduar nga sekuenca 110100. Le të përpiqemi të deshifrojmë këtë sekuencë. Meqenëse biti i parë është 1, karakteri i parë mund të jetë vetëm "m" ose "p" dhe përcaktohet nga vlera e bitit të dytë. Meqenëse biti i dytë është 1, karakteri i parë është "p". Biti i tretë është 0 dhe përputhet në mënyrë unike me karakterin "a". Biti i katërt është 1, domethënë, duhet të shikoni vlerën e bitit tjetër, i cili është 0, atëherë karakteri i tretë është "m". Biti i fundit është 0, i cili përputhet në mënyrë unike me karakterin "a". Kështu, vetia e kodeve të parashtesave, e cila konsiston në faktin se kodet më të shkurtra nuk mund të përkojnë me fillimin e kodeve më të gjata, bën të mundur dekodimin e paqartë të një mesazhi informacioni të koduar me kode prefiks me gjatësi të ndryshueshme.

Kodet e parashtesave zakonisht merren duke ndërtuar kodin (për sistemi binar) pemë. Çdo nyje e brendshme e një peme të tillë binare ka dy skaje dalëse, me një skaj që korrespondon me simbolin binar "0", dhe tjetri - "1". Për saktësi, mund të pajtohemi që skajit të majtë duhet t'i caktohet simboli "0", dhe skajit të djathtë - simboli "1".

Meqenëse nuk mund të ketë cikle në një pemë, mund të ketë gjithmonë vetëm një rrugë nga nyja rrënjë në nyjen e gjetheve. Nëse skajet e pemës janë të numëruara, atëherë çdo rrugë e tillë korrespondon me një sekuencë binare unike. Sekuenca e të gjitha sekuencave të tilla do të formojë një sistem kodesh parashtesash.

Për shembullin e konsideruar të një sistemi me tre kode parashtesash: (0, 10, 11), të cilat përcaktojnë simbolet "a", "m" dhe "p", pema e kodit është paraqitur në Fig. një.

Oriz. 1. Pema e kodit për sistemin
prej tre kodeve prefiks: (0, 10, 11)

Lehtësia e paraqitjes së pemës së kodeve të parashtesave qëndron në faktin se është struktura e pemës që bën të mundur formimin e kodeve me gjatësi të ndryshueshme që plotësojnë kushtin kryesor të kodeve të parashtesave, domethënë kushtin që kodet më të shkurtra të mos përkojnë me fillimi i kodeve më të gjata.

Deri më tani, ne kemi shqyrtuar vetëm idenë e kodeve të prefiksit me gjatësi të ndryshueshme. Sa i përket algoritmeve për marrjen e kodeve të prefiksit, ato mund të zhvillohen mjaft, por më të famshmet janë dy metoda: Shannon-Fano dhe Huffman.

Algoritmi Shannon-Fano

Ky algoritëm për marrjen e kodeve prefiks u propozua në mënyrë të pavarur nga R. Fano dhe K. Shannon, është si më poshtë. Në hapin e parë, të gjitha simbolet e sekuencës fillestare të informacionit renditen në probabilitete zbritëse ose në rritje të shfaqjes së tyre (frekuencat e shfaqjes së tyre), pas së cilës seria e renditur e simboleve në një vend ndahet në dy pjesë në mënyrë që në secilën prej tyre. shuma e frekuencave të simboleve është afërsisht e njëjtë. Si demonstrim, merrni parasysh fjalën tashmë të njohur "përplasje ajrore" .

Nëse simbolet që përbëjnë fjalën e dhënë, të renditura në rend zbritës të shpeshtësisë së shfaqjes së tyre, atëherë marrim sekuencën e mëposhtme: (a(5), m(2), v(1), u(1), k(1), c(1), p(1), o (1), f(1)) (në kllapa tregohet frekuenca e përsëritjes së një simboli në një fjalë). Më pas, ne duhet ta ndajmë këtë sekuencë në dy pjesë në mënyrë që në secilën prej tyre shuma e frekuencave të simboleve të jetë afërsisht e njëjtë (për aq sa është e mundur). Është e qartë se seksioni do të kalojë midis simboleve "t" dhe "c", si rezultat i të cilave formohen dy sekuenca: (a (5), t (2)) dhe (në (1), u (1 ), k (1), c(1), p(1), o(1), φ(1)). Për më tepër, shumat e frekuencave të përsëritjes së simboleve në sekuencën e parë dhe të dytë do të jenë të njëjta dhe të barabarta me 7.

Në hapin e parë të ndarjes së një sekuence karakteresh, marrim shifrën e parë të kodit të çdo karakteri. Rregulli këtu është i thjeshtë: për ato karaktere që janë në sekuencën në të majtë, kodi do të fillojë me "0", dhe për ata në të djathtë - me "1".

Në veçanti, sekuenca (a(5), m(2)) do të ndahet në dy karaktere të veçanta: a(5) dhe m(2) (nuk ka opsione të tjera ndarjeje). Atëherë shifra e dytë e kodit për simbolin "a" është "0", dhe për simbolin "t" - "1". Meqenëse, si rezultat i ndarjes së sekuencës, morëm elemente individuale, atëherë ato nuk janë më të ndashme dhe për simbolin "a" marrim kodin 00, dhe për simbolin "t" - kodin 01.

Sekuenca (në(1), u(1), k(1), c(1), p(1), o(1), f(1)) mund të ndahet ose në sekuenca (në(1), u(1), k(1)) dhe (c(1), p(1), o(1), φ(1)), ose në (v(1), u(1), k(1) ), (c(1)) dhe (p(1), o(1), φ(1)).

Në rastin e parë, shuma e frekuencave të simboleve në sekuencën e parë dhe të dytë do të jetë përkatësisht 3 dhe 4, dhe në rastin e dytë, përkatësisht 4 dhe 3. Për saktësi, ne përdorim opsionin e parë.

Për karakteret e sekuencës së re që rezulton (v(1), u(1), k(1)) (kjo është sekuenca e majtë), dy shifrat e para të kodit do të jenë 10, dhe për sekuencën (c( 1), p(1), o(1), f(1)) - 11.

Në shembullin tonë (Fig. 2 dhe 3), është marrë sistemi i mëposhtëm i kodeve të parashtesave: "a" - 00, "t" - 01, "c" - 100, "i" - 1010, "k" - 1011, "s" - 1100, "r" - 1101, "o" - 1110, "f" - 1111. Siç mund ta shihni, kodet më të shkurtra nuk janë fillimi i kodeve më të gjata, domethënë plotësohet vetia kryesore e kodeve të prefiksit. .

Oriz. 2. Demonstrimi i algoritmit Shannon-Fano

Oriz. 3. Pema e kodit për fjalën "përplasje ajrore"
në algoritmin Shannon-Fano

Algoritmi Huffman

Algoritmi Huffman është një tjetër algoritëm për marrjen e kodeve të prefiksit me gjatësi të ndryshueshme. Ndryshe nga algoritmi Shannon-Fano, i cili parashikon ndërtimin pema e kodit nga lart poshtë, ky algoritëm përfshin ndërtimin e një peme kodi në rend i kundërt, domethënë nga poshtë lart (nga nyjet e gjetheve në nyjen rrënjë).

Në fazën e parë, si në algoritmin Shannon-Fano, sekuenca fillestare e simboleve renditet në rend zbritës të shpeshtësisë së përsëritjes së simboleve (elementet e sekuencës). Për shembullin e diskutuar më parë me fjalën "përplasje ajrore" marrim sekuencën e mëposhtme të renditur të elementeve: (a(5), m(2), b(1), u(1), k(1), c(1), p(1), o(1), f(1)).

Më pas, dy elementët e fundit të sekuencës zëvendësohen nga një element i ri S1, të cilit i caktohet një përsëritje e barabartë me shumën e përsëritjeve elementet fillestare. Pastaj kryhet një renditje e re e elementeve të sekuencës në përputhje me përsëritjen e tyre. Në rastin tonë, dy elementët e fundit o(1) dhe f(1) zëvendësohen nga elementi S1(2), dhe sekuenca e renditur rishtazi do të marrë formën: (a(5), m(2), S1( 2), c(1), u(1), k(1), c(1), p(1)).

Vazhdimi i kësaj procedure të zëvendësimit të dy elementet e fundit sekuencë në një element të ri me përsëritshmëri totale dhe ri-renditje pasuese të sekuencës në përputhje me përsëritshmërinë e elementeve, do të vijmë në një situatë ku vetëm një element mbetet në sekuencë (Fig. 4).

Oriz. 4. Demonstrimi i algoritmit Huffman
në shembullin e fjalës "përplasje ajrore"

Njëkohësisht me zëvendësimin e elementeve dhe riorganizimin e sekuencës, ndërtohet një pemë binare e kodit. Algoritmi për ndërtimin e një peme është shumë i thjeshtë: operacioni i kombinimit (zëvendësimit) të dy elementeve të një sekuence gjeneron një element të ri nyje në pemën e kodit. Kjo do të thotë, nëse e shikoni pemën nga poshtë lart, skajet e pemës së kodit vijnë gjithmonë nga elementët e zëvendësuar dhe konvergojnë në një element të ri nyje që korrespondon me elementin e sekuencës së marrë nga zëvendësimi (Fig. 5). Në këtë rast, skajit të majtë të pemës së kodit mund t'i caktohet vlera "0", dhe skajit të djathtë - "1". Këto vlera më vonë do të shërbejnë si elementë kodi i prefiksit.

Oriz. 5. Ndërtimi i një peme kodi
në algoritmin Huffman
(duke zëvendësuar elementet "o" dhe "f"
element i ri S1)

Pema e plotë e kodit Huffman për një fjalë "përplasje ajrore" treguar në fig. 6.

Oriz. 6. Pema e kodit të plotë për fjalën "përplasje ajrore",
ndërtuar sipas algoritmit Huffman

Duke ecur përgjatë skajeve të pemës së kodit nga lart poshtë, është e lehtë të merrni kodet e parashtesave për të gjithë personazhet e alfabetit tonë informues:

Tani nëse përpiqeni të shkruani një fjalë "përplasje ajrore" në kodimin Huffman, marrim një sekuencë 41-bitësh 0 1101 11000 0 11001 0 111 0 1010 111 1011 1000 1001 0. Është interesante të theksohet se kur përdorim Shannon-Fano, marrim gjithashtu një kod prefiks 4. fjala “përplasje ajri”. Kjo do të thotë, në një shembull specifik, efikasiteti i kodimit të Huffman dhe Shannon-Fano është i njëjtë. Por nëse marrim parasysh se alfabeti i vërtetë i informacionit është 256 karaktere (dhe jo 14, si në shembullin tonë), dhe sekuencat reale të informacionit janë skedarë të çdo përmbajtje dhe gjatësi, atëherë lind pyetja për kodin optimal të prefiksit, d.m.th. , kodi që ju lejon të merrni gjatësinë minimale të sekuencës së daljes.

Mund të vërtetohet se sistemi i kodeve i marrë duke përdorur algoritmin Huffman është më i miri midis të gjitha sistemeve të mundshme të kodeve prefiks në kuptimin që gjatësia e sekuencës së informacionit të koduar që rezulton është minimale. Kjo do të thotë, algoritmi Huffman është optimal.

Disavantazhi kryesor i algoritmit Huffman është kompleksiteti i procesit të ndërtimit të një sistemi kodesh. Megjithatë, është algoritmi optimal Huffman ai që është algoritmi më i zakonshëm i gjenerimit të kodit me gjatësi të ndryshueshme dhe është i mishëruar në shumicën e shërbimeve për kompresimin dhe arkivimin e informacionit.

Kodimi aritmetik

Siç e kemi vërejtur tashmë, sipas kriterit Shannon, kodi optimal është ai në të cilin një kod me gjatësi –log 2 caktohet për çdo karakter. fq pak. Dhe nëse, për shembull, probabiliteti i një karakteri të caktuar është 0.2, atëherë gjatësia optimale e kodit të tij do të jetë -log 2 0.2 = 2.3 bit. Është e qartë se kodet e prefiksit nuk mund të ofrojnë një gjatësi të tillë kodi, dhe për këtë arsye nuk janë optimale. Në përgjithësi, gjatësia e kodit e përcaktuar nga kriteri Shannon është vetëm një kufi teorik. Pyetja e vetme është se cila metodë kodimi ju lejon të afroheni sa më afër këtij kufiri teorik. Kodet e prefikseve me gjatësi të ndryshueshme janë efikase dhe mjaft të lehta për t'u zbatuar, por ka më shumë mënyra efektive kodimi, në veçanti algoritmi i kodimit aritmetik.

Ideja e kodimit aritmetik është që në vend të kodimit të karaktereve individuale, kodi i caktohet njëkohësisht të gjithë sekuencës së informacionit. Në të njëjtën kohë, është e qartë se gjatësia e kodit për një karakter individual mund të mos jetë një numër i plotë. Kjo është arsyeja pse kjo metodë e kodimit është shumë më efikase se kodimi me prefiks dhe është më në përputhje me kriterin Shannon.

Ideja e algoritmit të kodimit aritmetik është si më poshtë. Si në të gjitha metodat e kodimit të konsideruara më parë, çdo simbol i sekuencës origjinale të informacionit karakterizohet nga probabiliteti i tij. Sekuencës origjinale të pakoduar i caktohet një gjysmë interval )

Artikujt kryesorë të lidhur