Bilgileri özlü bir biçimde kaydetme. Örneklerde verileri sıkıştırma

  • 28.06.2019

Bilgisayar 100 kitabından. Windows Vista'ya Başlarken yazar Zozulya Yuri

NTFS Dosyalarını Sıkıştırma NTFS dosya sistemiyle bölümleri kullanırken, dosyaları sıkıştırmak için onun yeteneklerini kullanabilirsiniz. Bu, ZIP veya RAR arşivlerini kullanmaktan daha zayıf sıkıştırmaya neden olur, ancak çok daha hızlıdır. NTFS ile sıkıştırılmış dosyalar

Sound Forge 9 kitabından yazar Quint Igor

Ses Sıkıştırma WAVE formatı, orijinal analog sinyalin verilerini oldukça doğru bir şekilde korur, ancak işgal edilen bilgi miktarı açısından çok savurgandır. Ancak bu format, ses verilerinin ilk kaydı için tercih edilir.

Microsoft Windows SharePoint Services 3.0 kitabından. Rus versiyonu. 9-16 Bölümler yazar Olga Londer

Access 2007 veritabanından SharePoint listesine veri aktarma Access 2007, bir tabloyu veya başka bir veritabanı nesnesini harici dosya, dBase veya Paradox veritabanı, Lotus dosyası 1-2-3, Excel 2007 çalışma kitabı gibi çeşitli biçimlerde dışa aktarmanıza olanak tanır , Word dosyası 2007 RTF, Metin Dosyası, XML Belgesi

Kitaptan Özet, dönem ödevi, bilgisayarda diploma yazar Balovsyak Nadezhda Vasilyevna

Grafik dosya biçimleri. Bir Görüntüyü Sıkıştırma Photoshop'ta görüntülerle çalışırken, bir dosyayı birkaç görüntü biçiminden birinde saklayabilirsiniz. Bunların en popülerleri JPEG, TIFF ve PSD'dir.JPEG, en küçük dosya ile en küçük dosyayı oluşturmanıza izin veren bir formattır.

Kitaptan Bilgisayarda çalışmak için en yeni eğitim yazar Beluntsov Valery

Sıkıştırılması Nadiren kullandığınız ve hala sabit diskinizde tutmak istediğiniz veri dosyalarının daha az yer kaplamaları için sıkıştırılması gerekir. Normal formlarında herhangi bir ortama sığmıyorlarsa, veri dosyalarının sıkıştırılması da gerekli olabilir.

TCP / IP Mimarisi, Protokoller, Uygulama kitabından (IP sürüm 6 ve IP Güvenliği dahil) tarafından Faith Sidney M

4.7.1 PPP'de Sıkıştırma Her kareye aynı adresi ve kontrol sekizlilerini dahil etmek pek mantıklı görünmeyebilir. PPP bağlantısının her bir ucundaki ortaklar, bu alanları hariç tutmak için sıkıştırma modunda çalışabilir.Protokol alanındaki değerler, olup olmadığını gösterir.

Ruby'de Programlama kitabından [Dil İdeolojisi, Uygulama Teorisi ve Uygulaması] tarafından Fulton Hal

Programcılar için Çalışmalar kitabından [tamamlanmamış, 1-24. bölümler] tarafından Weatherrell Charles

11. Daha az kopya - daha az saçmalık veya Metin ve dosya sıkıştırmanın fazlalığı Çoğu insanın aşırı derecede ayrıntılı olma eğiliminde olduğunu herkes bilir. En özlü ifadelerin bile büyük ölçüde azaltılabileceği çok daha az bilinir. Genel olarak doğal

Macromedia Flash Professional kitabından 8. Grafik ve Animasyon yazar Dronov V.A.

Flash video sıkıştırma. On2 VP6 ve Sorenson Spark Codec Bileşenleri Bölüm 1'de videodan bahsetmiştik. Şimdi öğrendiğimiz ve belki de çoktan unuttuğumuz her şeyi kısaca özetleyelim.Dolayısıyla, dosyada saklanan video bilgileri neredeyse her zaman sıkıştırılır. Aksi takdirde çalışmaz: veri içeren

Delphi'deki Temel Algoritmalar ve Veri Yapıları kitabından yazar Bucknell Julian M.

Bölüm 11. Veri sıkıştırma. Verileri düşündüğümüzde, genellikle bu verilerin aktardığı bilgilerden başka bir şey düşünmeyiz: bir müşteri listesi, bir ses CD'sindeki bir melodi, bir mektup ve benzerleri. Kural olarak, verilerin fiziksel temsili hakkında çok fazla düşünmüyoruz.

Bilgisayar Ses İşleme kitabından yazar Zagumenov Alexander Petrovich

Veri Sıkıştırma Verileri düşündüğümüzde, genellikle bu verilerin aktardığı bilgilerden başka bir şey düşünmeyiz: bir müşteri listesi, bir ses CD'sindeki bir melodi, bir mektup ve benzerleri. Kural olarak, verilerin fiziksel temsili hakkında çok fazla düşünmüyoruz. İlgilenmek

Dijital Fotoğrafçılık kitabından. Hileler ve efektler yazar Gursky Yuri Anatolievich

Minimum Yedeklilik Sıkıştırması Artık emrimizde bir bit akışı sınıfımız olduğuna göre, onu veri sıkıştırma ve kurtarma algoritmalarına bakarken kullanabiliriz. En az yedekli kodlama algoritmalarını inceleyerek başlıyoruz ve ardından

Yazarın kitabından

Kelime Sıkıştırma 1977 yılına kadar, sıkıştırma algoritmaları alanındaki ana çabalar, Shannon-Fano veya Huffman algoritmaları gibi minimum düzeyde fazlalıklı kodlama algoritmalarına odaklandı ve her ikisinden birine odaklandı.

Yazarın kitabından

Yazarın kitabından

Verilerin sıkıştırılması Herhangi bir ideal sıkıştırma yöntemi, gözle görülür bir kalite kaybına izin vermemelidir, yani veri miktarını azaltmak bilgi kaybına yol açmamalıdır. Bu, ses sinyalindeki tüm değişikliklerin duyulabilir eşiğin altında olması gerektiği anlamına gelir. Bu özellikle önemlidir

Yazarın kitabından

3.2. Dosya Boyutları ve Sıkıştırma Neden bir görüntüyü sıkıştırmanız gerekiyor? Altı megapiksellik bir kamerayla çekilen bir resim 18 MB bellekte yer kaplamalıdır. Görüntü bu formda belleğe kaydedilirse, büyük bir depolama aygıtı bile sığabilir.

Bilimsel danışmanım ve ben görüntü işleme üzerine küçük bir monografi hazırlıyoruz. HabraSociety'ye görüntü sıkıştırma algoritmalarına ayrılmış bir bölüm göndermeye karar verdim. Bütün bir bölümü tek bir gönderiye sığdırmak zor olduğu için, onu üç gönderiye bölmeye karar verdim:
1. Veri sıkıştırma yöntemleri;
2. Görüntülerin kayıpsız sıkıştırılması;
3. Kayıplı görüntülerin sıkıştırılması.
Serinin ilk yazısını aşağıdan okuyabilirsiniz.

Şu anda, şartlı olarak iki büyük gruba ayrılabilen çok sayıda kayıpsız sıkıştırma algoritması vardır:
1. Akış ve sözlük algoritmaları. Bu grup, RLE (çalışma uzunluğu kodlaması), LZ *, vb. ailelerinin algoritmalarını içerir.Bu grubun tüm algoritmalarının özelliği, kodlamanın mesajdaki karakterlerin frekansları hakkında bilgi kullanmaması, ancak daha önce karşılaştığımız diziler.
2. İstatistiksel (entropi) sıkıştırma için algoritmalar. Bu algoritma grubu, mesajda farklı karakterlerin meydana geldiği frekansların eşitsizliğini kullanarak bilgileri sıkıştırır. Bu gruptaki algoritmalar, aritmetik ve önek kodlama algoritmalarını içerir (Shannon-Fanno, Huffman, sekant ağaçları kullanılarak).
Bilgi dönüştürme algoritmaları ayrı bir gruba ayrılabilir. Bu grubun algoritmaları bilgiyi doğrudan sıkıştırmaz, ancak uygulamaları akış, sözlük ve entropi algoritmalarını kullanarak daha fazla sıkıştırmayı büyük ölçüde basitleştirir.

Akış ve sözlük algoritmaları

Uzunluk kodlamasını çalıştır

Run-Length Encoding (RLE), en basit ve en yaygın veri sıkıştırma algoritmalarından biridir. Bu algoritmada, tekrarlanan karakter dizisi bir karakterle değiştirilir ve tekrarlanma sayısı.
Örneğin, depolamak için 5 bayt gerektiren (bir baytın bir karakteri depolamak için ayrıldığı varsayılarak) "AAAAA" dizesi, iki bayttan oluşan "5A" ile değiştirilebilir. Açıkçası, tekrar serisi ne kadar uzun olursa, bu algoritma o kadar verimli olur.

Bu algoritmanın ana dezavantajı, tekrarlanmayan karakter dizileri üzerindeki son derece düşük verimliliğidir. Örneğin, "ABABAB" (6 bayt) dizisini düşünürsek, RLE algoritmasını uyguladıktan sonra "1A1B1A1B1A1B" (12 bayt) haline gelecektir. Yinelenmeyen karakterler sorunuyla başa çıkmak için çeşitli yöntemler vardır.

En basit yöntem aşağıdaki değişikliktir: tekrar sayısını kodlayan bayt, yalnızca tekrar sayısı hakkında değil, aynı zamanda bunların varlığı hakkında da bilgi depolamalıdır. İlk bit 1 ise sonraki 7 bit karşılık gelen karakterin tekrar sayısını, ilk bit 0 ise sonraki 7 bit tekrar yapılmadan alınması gereken karakter sayısını gösterir. Bu değişikliği kullanarak "ABABAB" kodlarsanız, "-6ABABAB" (7 bayt) elde ederiz. Açıktır ki, önerilen teknik, tekrarlanmayan karakter dizileri üzerinde RLE algoritmasının etkinliğini önemli ölçüde geliştirebilir. Önerilen yaklaşımın uygulanması Liste 1'de gösterilmektedir:

  1. tip
  2. işlev RLEEncode (InMsg: ShortString): TRLEEncodedString;
  3. MatchFl: boole;
  4. MatchCount: kısaltma;
  5. EncodingString: TRLEEncodedString;
  6. N, i: bayt;
  7. başlamak
  8. N: = 0;
  9. SetLength (EncodingString, 2 * uzunluk (InMsg));
  10. while uzunluk (InMsg)> = 1 do
  11. başlamak
  12. MatchFl: = (uzunluk (InMsg)> 1) ve (InMsg [1] = InMsg [2]);
  13. MatchCount: = 1;
  14. while (MatchCount<= 126 ) and (MatchCount < length(InMsg) ) and ((InMsg[ MatchCount] = InMsg[ MatchCount + 1 ] ) = MatchFl) do
  15. MatchCount: = MatchCount + 1;
  16. MatchFl ise
  17. başlamak
  18. N: = N + 2;
  19. EncodingString [N - 2]: = MatchCount + 128;
  20. EncodingString [N - 1]: = ord (InMsg [1]);
  21. Başka
  22. başlamak
  23. Eğer MatchCount<>uzunluk (InMsg) sonra
  24. MatchCount: = MatchCount - 1;
  25. N: = N + 1 + MatchCount;
  26. EncodingString [N - 1 - MatchCount]: = - MatchCount + 128;
  27. i için: = 1 MatchCount yapmak için
  28. EncodingString [N - 1 - MatchCount + i]: = ord (InMsg [i]);
  29. son;
  30. sil (InMsg, 1, MatchCount);
  31. son;
  32. SetLength (EncodingString, N);
  33. RLEEncode: = EncodingString;
  34. son;

Sıkıştırılmış bir mesajın kodunun çözülmesi çok basittir ve sıkıştırılmış mesajın üzerinden tek bir geçişe indirgenir, bkz. Liste 2:
  1. tip
  2. TRLEEncodedString = bayt dizisi;
  3. işlev RLEDecode (InMsg: TRLEEncodedString): ShortString;
  4. Tekrar Sayısı: shortint;
  5. ben, j: kelime;
  6. OutMsg: ShortString;
  7. başlamak
  8. OutMsg: = "";
  9. ben: = 0;
  10. ben iken< length(InMsg) do
  11. başlamak
  12. RepeatCount: = InMsg [i] - 128;
  13. ben: = ben + 1;
  14. Tekrar Sayısı ise< 0 then
  15. başlamak
  16. RepeatCount: = abs (RepeatCount);
  17. j için: = i ila i + RepeatCount - 1 do
  18. OutMsg: = OutMsg + chr (InMsg [j]);
  19. i: = i + Tekrar Sayısı;
  20. Başka
  21. başlamak
  22. j için: = 1'den RepeatCount'a
  23. OutMsg: = OutMsg + chr (InMsg [i]);
  24. ben: = ben + 1;
  25. son;
  26. son;
  27. RLEDecode: = OutMsg;
  28. son;

RLE algoritmasının verimliliğini artırmanın ikinci yöntemi, verileri doğrudan sıkıştırmayan, ancak sıkıştırma için daha uygun bir forma getiren bilgi dönüştürme algoritmalarının kullanılmasıdır. Böyle bir algoritmanın bir örneği olarak, Burrows-Wheeler dönüşümünün mucitlerinin adını taşıyan BWT permütasyonunu ele alacağız. Bu permütasyon karakterleri değiştirmez, sadece dizideki sıralarını değiştirir, permütasyon uygulandıktan sonra tekrarlanan alt diziler, RLE algoritması kullanılarak çok daha iyi sıkıştırılan yoğun gruplar halinde toplanır. Doğrudan BWT dönüşümü, aşağıdaki adımların sırasına indirgenir:
1. Orijinal dizeye başka hiçbir yerde bulunmayan özel bir satır sonu karakteri eklemek;
2. Orijinal dizinin tüm döngüsel permütasyonlarını almak;
3. Alınan satırları sözlük sırasına göre sıralama;
4. Ortaya çıkan matrisin son sütununu döndürme.
Bu algoritmanın uygulanması Liste 3'te gösterilmektedir.
  1. const
  2. EOMsg = "|" ;
  3. function BWTEncode (InMsg: ShortString): ShortString;
  4. OutMsg: ShortString;
  5. LastChar: ANSIChar;
  6. N, ben: kelime;
  7. başlamak
  8. InMsg: = InMsg + EOMsg;
  9. N: = uzunluk (InMsg);
  10. ShiftTable [1]: = InMsg;
  11. i için: = 2'den N'ye
  12. başlamak
  13. LastChar: = InMsg [N];
  14. InMsg: = LastChar + kopya (InMsg, 1, N - 1);
  15. ShiftTable [i]: = InMsg;
  16. son;
  17. Sırala (ShiftTable);
  18. OutMsg: = "";
  19. i için: = 1'den N'ye
  20. OutMsg: = OutMsg + ShiftTable [i] [N];
  21. BWTEncode: = OutMsg;
  22. son;

Bu dönüşümü açıklamanın en kolay yolu belirli bir örnektir. "ANANAS" dizesini alalım ve satırın sonundaki karakterin "|" sembolü olacağını kabul edelim. Bu satırın tüm döngüsel permütasyonları ve sözlükbilimsel sıralamalarının sonucu Tablo'da gösterilmektedir. 1.

Onlar. doğrudan dönüştürmenin sonucu "| ННАААС" dizesi olacaktır. Bu dizenin orijinalinden çok daha iyi olduğunu görmek kolaydır; RLE algoritması tarafından sıkıştırılmıştır, çünkü tekrarlanan harflerin uzun alt dizilerini içerir.
Benzer bir etki, diğer dönüşümlerin yardımıyla elde edilebilir, ancak BWT dönüşümünün avantajı, tersine çevrilebilir olmasıdır, ancak ters dönüşüm doğrudan olandan daha zordur. Orijinal dizeyi geri yüklemek için aşağıdakileri yapmanız gerekir:
Boş bir n * n matrisi oluşturun; burada n, kodlanmış mesajdaki karakter sayısıdır;
En sağdaki boş sütunu kodlanmış mesajla doldurun;
Tablo satırlarını sözlük sırasına göre sıralayın;
Boş sütunlar kalana kadar 2-3 arasındaki adımları tekrarlayın;
Satır sonu karakteriyle biten satırı döndürür.

İlk bakışta, tersine dönüşümün uygulanması zor değildir ve uygulama seçeneklerinden biri Liste 4'te gösterilmektedir.

  1. const
  2. EOMsg = "|" ;
  3. function BWTDecode (InMsg: ShortString): ShortString;
  4. OutMsg: ShortString;
  5. ShiftTable: ShortString dizisi;
  6. N, i, j: kelime;
  7. başlamak
  8. OutMsg: = "";
  9. N: = uzunluk (InMsg);
  10. SetLength (ShiftTable, N + 1);
  11. i için: = 0'dan N'ye
  12. ShiftTable [i]: = "";
  13. i için: = 1'den N'ye
  14. başlamak
  15. j için: = 1'den N'ye
  16. ShiftTable [j]: = InMsg [j] + ShiftTable [j];
  17. Sırala (ShiftTable);
  18. son;
  19. i için: = 1'den N'ye
  20. ShiftTable [i] [N] = EOMsg ise
  21. OutMsg: = ShiftTable [i];
  22. sil (OutMsg, N, 1);
  23. BWTDecode: = OutMsg;
  24. son;

Ancak pratikte verimlilik, seçilen sıralama algoritmasına bağlıdır. İkinci dereceden karmaşıklığa sahip önemsiz algoritmaların performans üzerinde son derece olumsuz bir etkisi olacağı açıktır, bu nedenle verimli algoritmaların kullanılması önerilir.

Yedinci adımda elde edilen tabloyu sıraladıktan sonra tablodan "|" karakteri ile biten bir satır seçmek gerekir. Bunun tek çizgi olduğunu görmek kolaydır. O. BWT dönüşümünü belirli bir örnek kullanarak inceledik.

Özetle, RLE algoritma grubunun ana avantajının basitlik ve işlem hızı (kod çözme hızı dahil) olduğunu ve ana dezavantajının tekrarlanmayan karakter kümelerinde verimsizlik olduğunu söyleyebiliriz. Özel permütasyonların kullanılması, algoritmanın verimliliğini arttırır, ancak aynı zamanda işlem süresini (özellikle kod çözme) büyük ölçüde artırır.

Sözlük sıkıştırma (LZ algoritmaları)

Sözlük algoritmaları grubu, RLE grubunun algoritmalarının aksine, karakterlerin tekrar sayısını değil, daha önce karşılaşılan karakter dizilerini kodlar. Söz konusu algoritmaların çalışması sırasında, önceden karşılaşılan dizilerin bir listesi ve bunlara karşılık gelen kodlarla dinamik olarak bir tablo oluşturulur. Bu tabloya genellikle sözlük denir ve buna karşılık gelen algoritma grubuna sözlük denir.

Sözlük algoritmasının en basit versiyonu aşağıda açıklanmıştır:
Giriş dizesinde görünen tüm karakterlerle sözlüğü başlatın;
Sözlükte kodlanmış mesajın başlangıcıyla eşleşen en uzun diziyi (S) bulun;
Bulunan dizinin kodunu yayınlayın ve kodlanmış mesajın başından kaldırın;
Mesajın sonuna ulaşılmamışsa, bir sonraki karakteri okuyun ve sözlüğe Sc ekleyin, 2. adıma gidin. Aksi takdirde çıkın.

Örneğin, "CUCKOOKUCHONKUPILACAPUCHON" ifadesi için yeni başlatılmış sözcük dağarcığı Tabloda gösterilmektedir. 3:

Sıkıştırma işlemi sırasında sözlük, mesajda bulunan dizilerle desteklenecektir. Sözlüğü yenileme süreci Tablo'da gösterilmektedir. 4.

Algoritma açıklanırken, sözlük tamamen doldurulduğunda durumun açıklaması kasıtlı olarak atlandı. Algoritmanın varyantına bağlı olarak farklı davranışlar mümkündür: sözlüğün tamamen veya kısmen boşaltılması, sözlüğün doldurulmasının durdurulması veya sözlüğün kod genişliğinde karşılık gelen bir artışla genişletilmesi. Bu yaklaşımların her birinin belirli dezavantajları vardır. Örneğin, sözlüğün tamamlanmasının durdurulması, sözlüğün sıkıştırılmış dizenin başında oluşan, ancak daha sonra oluşmayan dizileri sakladığı bir duruma yol açabilir. Aynı zamanda, sözlüğün temizlenmesi sık dizileri kaldırabilir. Kullanılan uygulamaların çoğu, sözlüğü doldururken sıkıştırma oranını izlemeye başlar ve belirli bir seviyenin altına düştüğünde sözlük yeniden oluşturulur. Ardından, sözlük dolduğunda doldurmayı durduran en basit uygulamayı ele alacağız.

Başlamak için, bir sözlüğü yalnızca karşılaşılan alt dizeleri değil, aynı zamanda sözlükte depolanan alt dizelerin sayısını da depolayan bir kayıt olarak tanımlayalım:

Daha önce karşılaşılan alt diziler, Words dizisinde saklanır ve kodları, bu dizideki alt dizilerin sayılarıdır.
Ayrıca sözlükte arama ve sözlüğe ekleme işlevlerini de tanımlayacağız:

  1. const
  2. MAX_DICT_LENGTH = 256;
  3. function FindInDict (D: TDictionary; str: ShortString): tamsayı;
  4. r: tam sayı;
  5. ben: tam sayı;
  6. fl: boole;
  7. başlamak
  8. r: = - 1;
  9. D. WordCount> 0 ise
  10. başlamak
  11. ben: = D. WordCount;
  12. fl: = yanlış;
  13. while (fl değil) ve (i> = 0) yapmak
  14. başlamak
  15. ben: = ben - 1;
  16. fl: = D. Sözcükler [i] = str;
  17. son;
  18. son;
  19. eğer fl ise
  20. r: = ben;
  21. FindInDict: = r;
  22. son;
  23. prosedür AddToDict (var D: TDictionary; str: ShortString);
  24. başlamak
  25. eğer D. WordCount< MAX_DICT_LENGTH then
  26. başlamak
  27. D. WordCount: = D. WordCount + 1;
  28. SetLength (D. Words, D. WordCount);
  29. D. Sözcükler [D. Sözcük Sayısı - 1]: = str;
  30. son;
  31. son;

Bu işlevleri kullanarak, açıklanan algoritmaya göre kodlama işlemi aşağıdaki gibi gerçekleştirilebilir:
  1. işlev LZWEncode (InMsg: ShortString): TEncodedString;
  2. OutMsg: TEncodedString;
  3. tmpstr: KısaDize;
  4. D: T Sözlük;
  5. i, N: bayt;
  6. başlamak
  7. SetLength (ÇıkışMsg, uzunluk (InMsg));
  8. N: = 0;
  9. InitDict (D);
  10. while uzunluk (InMsg)> 0 yapmak
  11. başlamak
  12. tmpstr: = InMsg [1];
  13. while (FindInDict (D, tmpstr)> = 0) ve (uzunluk (InMsg)> uzunluk (tmpstr))
  14. tmpstr: = tmpstr + InMsg [uzunluk (tmpstr) + 1];
  15. FindInDict (D, tmpstr) ise< 0 then
  16. sil (tmpstr, uzunluk (tmpstr), 1);
  17. OutMsg [N]: = FindInDict (D, tmpstr);
  18. N: = N + 1;
  19. sil (InMsg, 1, uzunluk (tmpstr));
  20. uzunluk (InMsg)> 0 ise
  21. AddToDict (D, tmpstr + InMsg [1]);
  22. son;
  23. SetLength (OutMsg, N);
  24. LZWEncode: = OutMsg;
  25. son;

Kodlamanın sonucu sözlükteki kelime numaraları olacaktır.
Kod çözme işlemi, kodların doğrudan şifresinin çözülmesine indirgenir, oluşturulan sözlüğün aktarılmasına gerek yoktur, kodun çözülmesi sırasında sözlüğün, kodlama sırasında olduğu gibi başlatılması yeterlidir. Ardından sözlük, kod çözme işlemi sırasında önceki alt diziyi ve geçerli sembolü birleştirerek doğrudan tamamen geri yüklenecektir.

Tek sorun şu durumda mümkündür: henüz sözlükte olmayan bir alt dizinin kodunun çözülmesi gerektiğinde. Bunun yalnızca mevcut adımda eklenecek bir alt diziyi çıkarmak gerektiğinde mümkün olduğunu görmek kolaydır. Bu, alt dizinin cSc modeliyle eşleştiği anlamına gelir, yani. aynı karakterle başlar ve biter. Ayrıca, cS önceki adımda eklenen alt dizidir. Dikkate alınan durum, henüz eklenmemiş bir satırın kodunun çözülmesinin gerekli olduğu tek durumdur. Yukarıdakileri göz önünde bulundurarak, sıkıştırılmış bir dizenin kodunu çözmek için aşağıdaki seçeneği önerebiliriz:

  1. işlev LZWDecode (InMsg: TEncodedString): ShortString;
  2. D: T Sözlük;
  3. OutMsg, tmpstr: KısaDize;
  4. ben: bayt;
  5. başlamak
  6. OutMsg: = "";
  7. tmpstr: = "";
  8. InitDict (D);
  9. i için: = 0 ila uzunluk (InMsg) - 1 do
  10. başlamak
  11. InMsg [i]> = D. WordCount ise
  12. tmpstr: = D. Words [InMsg [i - 1]] + D. Words [InMsg [i - 1]] [1]
  13. Başka
  14. tmpstr: = D. Sözcükler [InMsg [i]];
  15. OutMsg: = OutMsg + tmpstr;
  16. eğer i> 0 ise
  17. AddToDict (D, D. Words [InMsg [i - 1]] + tmpstr [1]);
  18. son;
  19. LZWDecode: = OutMsg;
  20. son;

Sözlük algoritmalarının avantajları, RLE'ye kıyasla daha yüksek sıkıştırma verimliliğini içerir. Bununla birlikte, bu algoritmaların gerçek kullanımının bazı uygulama zorlukları ile ilişkili olduğu anlaşılmalıdır.

entropi kodlaması

Shannon-Fano ağaçlarıyla kodlama

Shannon-Fano algoritması, geliştirilen ilk sıkıştırma algoritmalarından biridir. Algoritma, daha sık karakterleri daha kısa kodlar kullanarak temsil etme fikrine dayanmaktadır. Ayrıca, Shannon-Fano algoritması kullanılarak elde edilen kodlar, önek özelliğine sahiptir: yani. hiçbir kod başka bir kodun başlangıcı değildir. Önek özelliği, kodlamanın bire bir olmasını sağlar. Shannon-Fano kodlarını oluşturmaya yönelik algoritma aşağıda sunulmuştur:
1. Alfabeyi, sembollerin toplam olasılıkları birbirine mümkün olduğunca yakın olacak şekilde iki parçaya bölün.
2. Karakterlerin ilk bölümünün önek koduna 0, karakterlerin ikinci bölümünün önek koduna 1 ekleyin.
3. Her parça için (en az iki karakterli), 1-3 arasındaki adımları tekrarlayarak gerçekleştirin.
Karşılaştırmalı basitliğine rağmen, Shannon-Fano algoritmasının dezavantajları yoktur, bunlardan en önemlisi optimal olmayan kodlamadır. Her adımda bölümleme optimal olsa da, algoritma bir bütün olarak optimal bir sonucu garanti etmez. Örneğin, şu satırı düşünün: "AAAABVGDEZH". Karşılık gelen Shannon-Fano ağacı ve ondan türetilen kodlar Şekil 2'de gösterilmektedir. 1:

Kodlama olmadan, mesaj 40 bit kaplayacak (her karakterin 4 bit ile kodlandığı varsayılarak) ve Shannon-Fano algoritması kullanılarak 4 * 2 + 2 + 4 + 4 + 3 + 3 + 3 = 27 bit olacaktır. Mesaj hacmi %32,5 azaldı, ancak bu sonucun önemli ölçüde iyileştirilebileceği aşağıda gösterilecektir.

Huffman Ağaçları ile Kodlama

Shannon-Fano algoritmasından birkaç yıl sonra geliştirilen Huffman kodlama algoritması da önek özelliğine sahiptir ve buna ek olarak kanıtlanmış minimum fazlalık, son derece yaygın kullanımını tam olarak belirleyen şeydir. Huffman kodlarını elde etmek için aşağıdaki algoritma kullanılır:
1. Alfabenin tüm sembolleri serbest düğümler olarak temsil edilirken, düğümün ağırlığı mesajdaki sembolün frekansı ile orantılıdır;
2. Serbest düğümler kümesinden, minimum ağırlığa sahip iki düğüm seçilir ve seçilen düğümlerin ağırlıklarının toplamına eşit bir ağırlığa sahip yeni bir (ana) düğüm oluşturulur;
3. Seçilen düğümler ücretsiz listeden çıkarılır ve bunlara dayalı olarak oluşturulan üst düğüm bu listeye eklenir;
4. Serbest listede birden fazla düğüm olana kadar 2-3. adımlar tekrarlanır;
5. Oluşturulan ağaca bağlı olarak, alfabenin her karakterine bir önek kodu atanır;
6. Mesaj, alınan kodlarla kodlanır.

Shannon-Fano algoritmasında olduğu gibi aynı örneği düşünün. Huffman ağacı ve "AAAABVGDEZH" mesajı için elde edilen kodlar Şekil 2'de gösterilmektedir. 2:

Shannon-Fano algoritmasındakinden daha az olan kodlanmış mesajın boyutunun 26 bit olacağını hesaplamak kolaydır. Ayrı olarak, Huffman algoritmasının popülaritesi nedeniyle, şu anda Huffman kodlaması için, sembol frekanslarının iletilmesini gerektirmeyen uyarlamalı kodlama da dahil olmak üzere birçok seçenek olduğu belirtilmelidir.
Huffman algoritmasının dezavantajları arasında, uygulamanın karmaşıklığı ile ilgili problemlerin önemli bir kısmı vardır. Sembol frekanslarını depolamak için gerçek değişkenlerin kullanılması kesinlik kaybıyla ilişkilidir; bu nedenle pratikte tamsayı değişkenleri sıklıkla kullanılır, ancak ana düğümlerin ağırlığı sürekli artıyor, er ya da geç bir taşma meydana geliyor. Bu nedenle, algoritmanın basitliğine rağmen, doğru uygulanması özellikle büyük alfabeler için bazı zorluklara neden olabilir.

Sekant fonksiyon ağaçlarıyla kodlama

Sekant fonksiyonlarını kullanarak kodlama, önek kodlarının elde edilmesini sağlayan yazarlar tarafından geliştirilmiş bir algoritmadır. Algoritma, her düğümü bir sekant işlevi içeren bir ağaç oluşturma fikrine dayanmaktadır. Algoritmayı daha ayrıntılı olarak tanımlamak için birkaç tanım vermek gerekir.
Bir kelime, sıralı bir m bit dizisidir (m sayısına kelime uzunluğu denir).
Secant değişmezi, deşarj-deşarj değerinin bir çiftidir. Örneğin, değişmez (4,1), kelimenin 4 bitinin 1 olması gerektiği anlamına gelir. Eğer değişmez koşul karşılanırsa, değişmez doğru kabul edilir, aksi takdirde yanlıştır.
Bir k-bit sekant, bir dizi k değişmezidir. Tüm değişmez değerler doğruysa, o zaman sekant işlevinin kendisi doğrudur, aksi takdirde yanlıştır.

Ağaç, her düğümün alfabeyi mümkün olan en yakın parçalara böleceği şekilde inşa edilmiştir. İncirde. Şekil 3, bir sekant ağacının bir örneğini gösterir:

Genel durumda sekant fonksiyonları ağacı, optimal kodlamayı garanti etmez, ancak düğümlerdeki işlemin basitliği nedeniyle son derece yüksek bir çalışma hızı sağlar.

aritmetik kodlama

Aritmetik kodlama, bilgiyi sıkıştırmanın en etkili yollarından biridir. Huffman algoritmasının aksine, aritmetik kodlama, sembol başına 1 bitten daha az bir entropi ile mesajları kodlamanıza izin verir. Çünkü aritmetik kodlama algoritmalarının çoğu patentlerle korunmaktadır, aşağıda sadece temel fikirler açıklanacaktır.
Kullanılan alfabede sırasıyla p_1,…, p_N frekanslarıyla a_1,…, a_N N sembolü olduğunu varsayalım. Ardından aritmetik kodlama algoritması şöyle görünecektir:
Çalışan bir yarım aralık olarak, genel olarak Bilgi teknolojisi konularını alın Eş anlamlılar bilgi azaltma TR bilgi azaltma ...

SIKIŞTIRMA BİLGİLERİ- (veri sıkıştırma) bilgilerin (verilerin) orijinalinden daha az bitte sunulması. Fazlalığı ortadan kaldırmaya dayalıdır. Ayırt S. ve. bilgi kaybı olmadan ve çözülmekte olan görevler için önemsiz olan bazı bilgilerin kaybıyla. İLE… … Ansiklopedik Psikoloji ve Pedagoji Sözlüğü

uyarlanabilir kayıpsız sıkıştırma- - [L.G. Sumenko. İngilizce Rusça Bilgi Teknolojileri Sözlüğü. M.: GP TsNIIS, 2003.] Konular genel olarak bilgi teknolojileri EN uyarlanabilir kayıpsız veri sıkıştırmaALDC ... Teknik çevirmen kılavuzu

bilgilerin sıkıştırılması / sıkıştırılması- - [L.G. Sumenko. İngilizce Rusça Bilgi Teknolojileri Sözlüğü. M .: GP TsNIIS, 2003.] Genel olarak bilgi teknolojileri konuları EN sıkıştırma ... Teknik çevirmen kılavuzu

dijital bilgi sıkıştırma- - [L.G. Sumenko. İngilizce Rusça Bilgi Teknolojileri Sözlüğü. M.: GP TsNIIS, 2003.] Konular genel olarak bilgi teknolojileri EN sıkıştırma ... Teknik çevirmen kılavuzu

Ses basit bir dalgadır ve dijital bir sinyal bu dalganın bir temsilidir. Bu, analog sinyalin genliğinin bir saniye içinde birden çok kez kaydedilmesiyle elde edilir. Örneğin, sıradan bir CD'de bir sinyal 44100 kez ... ... Wikipedia'da hafızaya alınır.

Artıklığı azaltarak veri miktarını azaltan bir süreç. Veri sıkıştırma, standart boyutlu veri parçalarının sıkıştırılmasını içerir. Kayıplı ve kayıpsız sıkıştırma arasında bir ayrım yapılır. İngilizce: Veri ... ... finansal kelime hazinesi

dijital harita sıkıştırma- Sunumunun gerekli doğruluğu dahilinde fazlalığın ortadan kaldırılması da dahil olmak üzere hacmini azaltmak için dijital kartografik bilgilerin işlenmesi. [GOST 28441 99] Konular dijital haritacılık Terimleri, yöntemleri ve teknolojileri genelleştirme ... ... Teknik çevirmen kılavuzu

Çoğu veri türünün karakteristik bir özelliği, fazlalık... Veri fazlalığının derecesi, veri türüne bağlıdır.
Örneğin, video verileri için, artıklık derecesi, grafik verilerden birkaç kat daha fazladır ve grafik verilerinin artıklık derecesi, sırayla, metinsel verilerin artıklık derecesinden daha büyüktür.

Başka bir faktör artıklık derecesini etkileyen, benimsenen kodlama sistemidir. Kodlama sistemlerine bir örnek, düşünceleri ifade etmek için kavramları ve fikirleri kodlamak için sistemlerden başka bir şey olmayan sıradan iletişim dilleri olabilir. Böylece, Rus dilinin araçlarını kullanarak metin verilerinin kodlanmasının, İngilizce dilini kullanan benzer verilerin kodlanmasından ortalama olarak %20-25 daha fazla fazlalık sağladığı bulunmuştur.

Erkek için fazlalık veri genellikle bağlı ile birlikte kalite fazlalık, bilginin anlaşılırlığını ve kavranmasını iyileştirme eğiliminde olduğundan, bilgi. Ancak, bilgi depolamak ve iletmek söz konusu olduğunda bilgisayar teknolojisi sayesinde, sonra fazlalık olumsuz bir rol oynar, çünkü bilgi depolama ve aktarma maliyetinde bir artışa yol açar. Bu sorun, özellikle büyük hacimli bilgilerin küçük hacimli veri taşıyıcıları ile işlenmesi durumunda acil hale gelir. Bu bağlamda sürekli olarak fazlalığın azaltılması veya veri sıkıştırma sorunu ortaya çıkmaktadır.

Eğer bitmiş dosyalara veri sıkıştırma teknikleri uygulanır, daha sonra genellikle "veri sıkıştırma" terimi yerine "veri arşivleme" terimini kullanırlar, sıkıştırılmış verilerin varyantına arşiv denir ve yazılım sıkıştırma yöntemleri uygulayanlara arşivleyiciler denir.

Sıkıştırılacak verilerin bulunduğu nesneye bağlı olarak şunlar vardır:

· Dosyaların sıkıştırılması (arşivlenmesi): Dosyaların iletişim kanalları aracılığıyla iletilmesi veya küçük kapasiteli harici depolama ortamında taşınması için hazırlanırken dosya boyutunu küçültmek için kullanılır;

· Klasörlerin sıkıştırılması (arşivlenmesi): örneğin yedeklerken, uzun süreli depolamadan önce klasörlerin hacmini azaltmanın bir yolu olarak kullanılır;

· Disklerin sıkıştırılması (sıkıştırılması): Verileri bir depolama ortamına yazarken (genellikle işletim sistemi aracılığıyla) sıkıştırarak geniş bir disk kullanma verimliliğini artırmak için kullanılır.

çok pratik var algoritmalar veri sıkıştırma, ancak hepsi dayanmaktadır üç Veri fazlalığını azaltmanın teorik yolları.

İlk yol değiştirmek veri içeriği,

İkinci - değişimde yapılar veri,

üçüncü - içinde eşzamanlı değişim Verinin hem yapısı hem de içeriği.

Veri sıkıştırma gerçekleşirse değişim içeriklerini, daha sonra sıkıştırma yöntemi aranan geri döndürülemez, yani, verileri arşivden geri yüklerken (açarken) bilgiler tamamen geri yüklenmez. Bu tür yöntemlere genellikle denir kayıp kontrollü sıkıştırma yöntemleri... Bu yöntemlerin yalnızca içeriğin bir kısmının kaybının önemli bilgi bozulmasına yol açmadığı veri türleri için kullanılabileceği açıktır. Bu veri türleri video, ses ve grafikleri içerir. Kayıp kontrollü sıkıştırma teknikleri, önemli ölçüde daha yüksek sıkıştırma oranları sağlar, ancak bunların yasaktır başvurmak metin verisi... Kayıplı sıkıştırma biçimlerinin örnekleri şunları içerir:

· JPEG - grafik verileri için;

· MPG - video verileri için;

· MP3 - ses verileri için.

Yalnızca veri sıkıştırma gerçekleşirse yeniden yapılandırma veri,
sonra sıkıştırma yöntemi aranan tersine çevrilebilir... Bu durumda, bilgileri tamamen arşivden geri yükleyebilirsiniz. Tersinir sıkıştırma yöntemleri herhangi bir veri türüne uygulanabilir, ancak az Geri dönüşü olmayan sıkıştırma yöntemlerine kıyasla sıkıştırma oranı. Kayıpsız sıkıştırma biçimlerine örnekler:

· GIF, TIFF - grafik verileri için;

AVI - video verileri için;

ZIP, ARJ, RAR, CAB, LH - isteğe bağlı veri türleri için.

Çok var bilgi kaybı olmadan farklı pratik sıkıştırma yöntemleri, kural olarak, farklı veri türleri ve farklı hacimler için farklı verimliliğe sahiptir. Ancak, bu yöntemler üç teorik algoritmaya dayanmaktadır:

RLE (Çalışma Uzunluğu Kodlaması) algoritması;

KWE grubunun algoritmaları (KeyWord Encoding);

· Huffman'ın algoritması.

RLE algoritması

RLE algoritması, tekrar eden veri dizilerini tespit etme ve bunları veri kodunu ve tekrarlama oranını belirten daha basit bir yapı ile değiştirme fikrine dayanmaktadır. Örneğin, size sıkıştırmaya tabi bir veri dizisi verildiğini varsayalım:

1 1 1 1 2 2 3 4 4 4

RLE algoritması, onu aşağıdaki yapıyla değiştirmeyi önerir: 1 4 2 2 3 1 4 3, burada her bir sayı çiftinin ilk sayısı veri kodudur ve ikincisi tekrarlama faktörüdür. Giriş dizisindeki her veri öğesini depolamak için 1 bayt tahsis edilirse, tüm dizi 10 bayt bellek kaplarken, çıkış dizisi (sıkıştırılmış sürüm) 8 bayt bellek kaplar. Sıkıştırma oranı sıkıştırma oranını karakterize eden , formülle hesaplanır.

Nasıl daha küçük sıkıştırma oranı değeri, daha verimli sıkıştırma yöntemi. Tekrarlayan veri dizisinin uzunluğu daha uzun olduğunda RLE algoritmasının daha iyi bir sıkıştırma etkisi vereceği açıktır. Yukarıdaki örnekte, giriş sırası şöyle görünüyorsa: 1 1 1 1 1 1 3 4 4 4, sıkıştırma oranı %60 olacaktır. Bu bağlamda, grafik verileri sıkıştırılırken (özellikle tek renkli görüntüler için) RLE algoritmasının daha yüksek verimliliği elde edilir.

KWE grubunun algoritmaları

Anahtar sözcük sıkıştırma algoritması, sözcük birimlerini sabit uzunluktaki bayt gruplarında kodlama ilkesine dayanır. Sözcük biriminin bir örneği, sıradan bir kelime olacaktır. Uygulamada, daha kısa uzunlukta bir karakter zinciri (kod) ile kodlanmış sözcük birimlerinin rolü için yinelenen karakter dizileri seçilir. Kodlama sonucu tabloya yerleştirilir ve sözde sözlük.

Bu algoritmanın, aralarında en yaygın olanı Lempel-Ziva algoritması (LZ algoritması) ve modifikasyonu olan Lempel-Ziva-Welch algoritması (LZW algoritması) olan birkaç uygulaması vardır. Bu algoritmadaki sözlük, potansiyel olarak sonsuz bir kelime öbeği listesidir. Algoritma, NULL dize olarak adlandırılan yalnızca bir kodlanmış dize içeren neredeyse boş bir sözlükle başlar. Girilen veri dizisinin sonraki karakteri okunurken, mevcut satıra eklenir. İşlem, geçerli satır sözlükteki herhangi bir ifadeyle eşleştiği sürece devam eder. Ancak er ya da geç, geçerli satır sözlükteki herhangi bir ifadeyle eşleşmeyi bırakır. Geçerli satır, sözlükle son eşleşme ve az önce okunan mesaj karakteri olduğunda, kodlayıcı, eşleşmenin dizinini ve ardından satırların eşleşmesini bozan karakterden oluşan bir kod verir. Eşleşme dizini ve ardından karakterden oluşan yeni bir ifade sözlüğe eklenir. Bu ifade bir dahaki sefere bir mesajda göründüğünde, bilgi sıkıştırma derecesini artıran daha uzun bir ifade oluşturmak için kullanılabilir.

LZW algoritması, sıkıştırılmış mesajın karakter dizilerini sabit uzunlukta kodlarla değiştiren bir cümle tablosu (sözlük) etrafında oluşturulmuştur. Tablo, sözde avans özelliğine sahiptir, yani, bazı w grubu ve K sembolünden oluşan sözlüğün her bir ifadesi için, w ifadesi de sözlüğe girilir. Sözlüğün tüm bölümleri tamamen doldurulursa, kodlama uyarlamalı olmaktan çıkar (kodlama, sözlükte zaten mevcut olan ifadelere dayanmaktadır).

Bu gruptaki sıkıştırma algoritmaları en çok etkili için Metin büyük veri hacimleri ve küçük dosyalar için etkisizdir (sözlüğü kaydetme ihtiyacı nedeniyle).

Huffman algoritması

Huffman algoritması, bit grupları halinde kodlama fikrine dayanmaktadır. İlk olarak, giriş veri dizisinin bir frekans analizi gerçekleştirilir, yani içinde bulunan her sembolün oluşma sıklığı ayarlanır. Bundan sonra, karakterler azalan oluşum sıklığına göre sıralanır.

Ana fikirşu şekildedir: bir karakter ne kadar sık ​​ortaya çıkarsa, o kadar az bit kodlanır. Kodlamanın sonucu, kod çözme için gerekli sözlüğe girilir.

Veri sıkıştırma

Mihail Svariçevski

Verilerin sıkıştırılması (sıkıştırılması), daha az yer kaplayan bir forma dönüştürülmesine denir. Bu formda, verilerin depolanması hem daha kolaydır (depolama cihazları hala kauçuk değildir) hem de sınırlı bant genişliğine sahip kanallar üzerinden aktarım çok daha keyiflidir.

Tüm sıkıştırma algoritmaları iki türe ayrılır: kayıplı ve kayıpsız.

Kayıplı sıkıştırma, çok daha yüksek bir sıkıştırma oranı elde etmenizi sağlar (orijinal hacmin 1/30 veya daha azına kadar).
Örneğin paketlenmemiş halde 30 gigabayt alan bir video 1 CD'ye kaydedilebilir.
Ancak kayıplı sıkıştırma algoritmaları verilerin kendisinde bazı değişikliklere neden olur; bu nedenle, bu tür algoritmalar yalnızca küçük bozulmaların önemsiz olduğu verilere uygulanabilir: video, fotoğraf görüntüleri (JPEG algoritmaları), ses (MP3 algoritması).

Kayıpsız sıkıştırma elbette o kadar etkili değildir (derecesi belirli verilere çok bağlıdır), ancak paketin açılmasından sonraki veriler orijinaliyle tamamen aynıdır. Bu, örneğin metin verileri, program kodu için kesinlikle gereklidir. Bu makale kayıpsız sıkıştırmaya odaklanacaktır.

Kayıpsız sıkıştırma algoritmalarının çoğu iki gruba ayrılır: ilk olarak kaynak dosyanın parçalarından bir biçimde metin oluşturur (sözlük yöntemleri); ikincisi (istatistiksel yöntemler), dosyada farklı karakterler veya karakter gruplarının farklı olasılıklarla görünmesi gerçeğinden yararlanır (örneğin, metin dosyalarında "a" harfi "b"den çok daha sık geçer).

Sözlük yöntemleri

Sözlük yöntemleri, yüksek sıkıştırma / açma hızı ile karakterize edilir, ancak biraz daha kötü sıkıştırma. Bir kelime bir karakter dizisidir. Genel olarak, elbette, sembollerden değil, baytlardan bahsediyoruz; ancak basitlik için örneklerde ASCII karakterleri kullanılacaktır.

Sözlük bir dizi kelime içerir (genellikle 2x; örneğin, 4096).
Sıkıştırma, sözlükteki kelime numarasının genellikle kelimenin kendisinden çok daha kısa olması nedeniyle sağlanır.
Sözlük sıkıştırma algoritmaları iki gruba ayrılır:
1) açık bir sözlük kullanarak (LZ78, LZW, LZC, LZT, LZMV, LZJ, LZFG algoritmaları)
Örneğin, sözlüğe göre
1. "Çoğunluk"
2. "sıkıştırma"
3. "olmadan"
4. "kayıp"
5. "algoritmalar"
"En kayıpsız sıkıştırma algoritmaları" metni "15234" olarak sıkıştırılır.

2) kelime numarası yerine belirtme - geçerli konuma göre konum ve tekrarlanan bölümün uzunluğu (algoritmalar LZ77, LZR, LZSS, LZB, LZH)
Örneğin, "ababbababbabwgbbabw" metni
"05ababb5504abvg65" değerine küçülür, burada:
"05ababb" - 0 konumu, 5 karakterin daha sıkıştırılmamış olduğu anlamına gelir.
"55" - Mevcut konumdan 5 karakter gerideki konumdan 5 harf.
"04abvg" - 4 karakter daha sıkıştırılmamış.
"65" – Mevcut olandan 6 karakter geride konumdan 5 harf.

LZ algoritmalarının modifikasyonları sadece sözlüğü temsil etme, kelime arama ve ekleme yollarında farklılık gösterir. Bazıları daha hızlı sıkar, ancak daha da kötüsü; diğerleri daha fazla bellek gerektirir.

Değiştirilmiş LZ77 algoritmasına daha yakından bakalım.
Arşiv, aşağıdaki biçimdeki kayıtlardan oluşacaktır:
(n, m) - m uzunluğundaki dizenin geçerli konumdan itibaren n konumundan başladığı anlamına gelir.
(0, m, "m karakter") - sıkıştırılamayan daha fazla m karakterin takip ettiği anlamına gelir.

Sıkıştırma algoritması aşağıdaki gibi olacaktır: Dosyada, en uzun dizinin geldiği, mevcut bayttan başlayan diziyle çakışan bir yer arıyoruz. Uzunluğu 3'ten fazla ise dizinin başlangıcını ve uzunluğunu arşive yazarız; aksi takdirde 0, dizinin uzunluğu ve sıkıştırılmamış karakterlerin kendisini yazarız. Paketi açmak daha da kolaydır: arşiv dosyası bitene kadar her biri 2 sayı (n, m) okuruz. n = 0 ise, arşivden m sembolünü hemen arabelleğe koyarız (bu sembollere hala ihtiyacımız var) ve bunları çıktı dosyasına yazarız. eğer n<>0 daha sonra n konumundaki arabellekteki m öğelerini arabelleğe ve çıktı dosyasına kopyalayın.

Ancak iki sorun var:
1) Sınırlı arabellek boyutu: 100 MB boyutundaki bir dosyayı sıkıştırmamız gerekirse, onu hiçbir şekilde arabelleğe koymayacağız. Bu nedenle, dolduğunda (örneğin %75), içindeki verileri başa kaydırmanız gerekecektir (örneğin %25; tabii ki en eski karakterler kaybolacaktır). Bu, sıkıştırmayı düşürür, ancak algoritmayı daha az bellek yoğun hale getirir.
2) Sıkıştırma programının hızı çok yavaş. Gerçekten de, 10 KB'lık bir dosyayı sıkıştırmamız gerekirse, bu en az yaklaşık 10.000 * 10.000 / 2 işlem yapmamızı gerektirecektir (eşleşen bir alt diziyi 10.000 kez aramamız gerekecek ve bu tür her arama ortalama 10.000/2 sürecektir). operasyonlar). Arama işlemini hızlandırmak için chr (0), chr (2) ... chr (255) karakteriyle başlayan dizilerin konum numaralarını ayrı bir dizide saklayabilirsiniz. Ardından, arama yaparken, yalnızca ilk harfi istenen dizinin ilk harfiyle çakışan kombinasyonları kontrol etmemiz gerekecek.

İstatistiksel Yöntemler

İstatistiksel yöntemler, sözlük yöntemlerinden çok daha yavaştır, ancak daha güçlü sıkıştırma sağlar. Onlarda, her harf bir kodla değiştirilir. Kod, bir karakteri benzersiz olarak tanımlayan birkaç bittir. İstatistiksel teknikler, en yaygın karakterleri daha kısa kodlarla eşleştirmek için çeşitli teknikler kullanır. Harfleri oluşma sıklıklarına göre kodlamak için iki ana algoritma vardır:

1) Huffman kodları: tüm karakterler bir tam sayı bit ile kodlanmıştır; ve böylece kod çözme her zaman nettir (örneğin, "a" harfi "1001" ve "b" - "10010" bit dizisine karşılık geliyorsa, kod çözme belirsizdir). Avantaj - yüksek sıkıştırma hızı. Dezavantajları - yetersiz sıkıştırma, uyarlamalı seçeneğin uygulanmasındaki zorluklar. Son zamanlarda, gerçek kodlama algoritmasının hızı giderek daha küçük bir rol oynadığından (istatistiksel bilgi toplama algoritmaları daha yavaş ve daha yavaş çalışır ve kodlayıcının çalışma süresindeki 2 katlık bir artış bile hızı pratik olarak etkilemez), bu algoritma, aritmetik kodlamaya göre önemli bir avantajı yok. ...

2) Aritmetik kodlama: her karakter için, segmentte bir boşluk belirlenir ve bu segmentin genişliğine bağlı olarak, göreceli olarak, hatta kesirli bile farklı sayıda bit tahsis edilebilir (örneğin: "a" dizesine izin verin) 0'a karşılık gelir ve "ab" dizisi - 1, ardından "aba" dizisi 2 bit olarak kodlanır, yani karakter başına ortalama 2/3 bit). Bu yöntem istatistiksel bilgileri daha doğru kullanır ve her zaman Huffman algoritması kadar iyi, ancak daha yavaş sıkıştırır. Avantajlar - teorik olarak elde edilebilecek maksimum sıkıştırma oranı, uyarlanabilir versiyonun basit uygulaması. Dezavantajları - biraz daha düşük hız.

Aritmetik kodlama nasıl çalışır:

Örneğin, "a", "b" - ve "c" - karakterlerine bir boşluk atadık. O zaman elimizde 0,4 sayısı varsa, o zaman "b" harfinin kodlanmış olduğunu söyleyebiliriz (0,3<=0.4<=0.6), а если 0.9 – то c(0.6<=0.9<=1). Итак, у нас получилось закодировать 1 букву в число. Как же закодировать 2 буквы? Очень просто: например, если первая буква – "b", то интервал равен . Разделим этот интервал на части, в отношении наших первоначальных отрезков. Тогда 2-м буквам "ba" будет соответствовать интервал , "bb" – и "bc" – . Для раскодирования нам достаточно знать любое число из этого интервала.

Şifreyi çözmeye çalışalım: 0.15 sayısı verilsin. Bu sayı, ilk kodlanan harfin "a" olduğu anlamına gelen "a" harfinin aralığına düşer. İkinci harfi bulmak için, sayıyı aralıktaki harfi gösterecek şekilde değil, ancak. Bunu yapmak için, ilk aralığın (0) alt sınırını sayıdan çıkarın ve aralığın genişliğine bölün (0,3-0 = 0,3). Yeni bir sayı (0,15-0) /0,3 = 0,5 elde ederiz. Aynı adımları tekrarladıktan sonra ikinci harfin "b" olduğunu öğreniyoruz. 3 veya daha fazla harf kodlanmış olsaydı, bu işlemi birçok kez tekrarlayarak tüm harfleri bulurduk.

Sayı gösterimi neden verileri sıkıştırmanıza izin verir:
Daha olası karakterler daha geniş bir aralığa karşılık gelir ve böyle bir harfi kodladıktan sonra aralık fazla azalmayacaktır, bu nedenle bu aralıktan herhangi bir sayıyı temsil etmek için çok daha fazla bit gerekli değildir.

Sıkıştırma algoritması:
Her karakter için, verilerdeki sıklığa (buluşma olasılığına) göre uygun bir aralık atamalıyız: "a" karakterinin olasılığı 0,4, "b" - 0,3 ve "c" - ayrıca 0,3; daha sonra "a" sembolü "b" -, "c" - aralığına karşılık gelir. Yani, gerekli tüm harfler arasındaki boşluğu, karşılaşma olasılıklarına göre böleriz (daha olası sembol, daha büyük bir boşluğa karşılık gelir).

Sıkıştırma işleminde 2 sınırımız var: üst ve alt, sırasıyla hi ve lo diyelim. Boşluğu atadığımız karakteri kodlamamız gerektiğini varsayalım. Ardından, yayılma alanımıza bir karakter aralığı "eklenir" ve lo, eklenen aralığın alt sınırına, hi - üst sınırına eşit olacaktır. Sonuç olarak, kodlama ilerledikçe lo ve hi arasındaki boşluk daralır ve daralır. Son olarak tüm verileri kodladığımızda ortaya çıkan aralıktan herhangi bir sayıyı seçip yazdırıyoruz. Sıkıştırılmış veri olacak.

Ambalajın açılması:
Semboller ve sıkıştırma için boşlukları oluşturalım. Arşiv numarasının arasına düştüğü karakter, verilerin ilk karakteridir. Karakterin yayılımını arşiv numarasıyla birlikte "uzatın" (yani, yeni kodu çözülen karakterin aralığının alt sınırını çıkarın ve bu aralığın genişliğine bölün), ardından işlemi her şey tamamlanana kadar tekrarlayın. kodu çözüldü.

Sorunlar:
Her şey bu kadar basit olsaydı... Aslında, arşiv numarasını saklamak için çok yüksek bir hassasiyete (onlarca ve yüz binlerce karakter) ihtiyacınız olacak, bu yüzden pratikte sıradan veri türlerini kullanmanız gerekiyor. Bunu başarmak için arşiv numarasının en önemli bitlerine / rakamlarına bakacağız. Hi ve lo ile eşleşir eşleşmez onları hemen arşive yazıp "kesebiliriz". Paketi açarken, tam tersine, aralığı birkaç katına çıkardığımızı gördüğümüzde, arşiv dosyasından birkaç rakam sayar ve bunları arşiv numaramızın sonuna ekleriz.
Aritmetik kodlamanın bir modifikasyonu sıklıkla kullanılır - aralık kodlayıcı. Ana fark, ilk aralıktır -. Bu, işin hızına yansıyan verileri bit bazında değil, hemen bayt bazında çıktı almanıza olanak tanır. Makalenin sonunda, bu özel seçeneğin uygulanması verilmiştir.

Sembollerin olasılıklarının belirlenmesi

Hız ve sıkıştırma oranını etkileyen ana süreç, sembollerin olasılıklarının belirlenmesidir. En basit durumda, bir karakterin olasılığını - zaten kodlanmış bir veri parçasındaki oluşum sayısının, verilerdeki toplam karakter sayısına bölünmesiyle - ele alacağız. Metinler için bu, yaklaşık 2 kat sıkıştırma sağlar. Artırmak için, örneğin, "u" dan sonra "i" sembolüyle karşılaşma olasılığının neredeyse 0'a eşit olduğu ve "c" den sonra "o"nun yaklaşık 0,25 olduğu gibi gerçekleri dikkate alabilirsiniz. Bu nedenle, önceki her sembol için olasılıkları ayrı ayrı hesaplayacağız.

Sıkıştırılacak veriler hakkında yaptığımız varsayımlara (örneğin, olasılığın önceki sembollere bağımlılığı) olasılık modeli denir. Olasılıkların önceki sembollere bağlı olmadığı bir modele 0 dereceli model denir. Olasılıklar önceki sembolün 1'ine bağlıysa, o zaman bu 1. dereceden bir modeldir, eğer son 2'den ise 2., vb. Yüksek dereceli modellerde sembollerin olasılıklarını verimli bir şekilde hesaplamak için özel bir algoritma grubu vardır - PPM ve modifikasyonları.
Modeller uyarlanabilir olmayan, yarı uyarlanabilir ve uyarlanabilir olabilir. Uyarlanabilir olmayan yöntemlerde, tüm karakterlerin olasılıkları programa sabit kodlanmıştır. Giriş verilerine göre yarı uyarlamalı olarak 2 geçiş yapılır: 1. - olasılıkları belirlemek için, 2. - sıkıştırmanın kendisi için. Uyarlanabilir - Sıkıştırma işlemi sırasında simgelerin olasılıkları değişir. Uyarlanabilir modeller en yavaş olanlardır, ancak verileri uyarlanabilir olmayan ve yarı uyarlanabilir modellerden daha güçlü bir şekilde sıkıştırma eğilimindedirler. Genel olarak, tüm modeller arasında, sıkıştırılacak veriler hakkında en fazla bilgiyi kullananlar daha iyi sıkıştırılır - önceki karakterlere bağımlılık, bazı gerçekler, örneğin: metinlerde, bir noktadan sonra genellikle büyük harf gelir, vesaire.

Popüler arşivleyicilerde kullanılan algoritmalar:

ZIP, ARJ, RAR - LZ + Huffman
HA - PPM + Aritmetik Kodlama
BOA - BWT + Aritmetik Kodlama
UHARC - LZ + PPM + Aritmetik Kodlama
(Burada "+" işaretinin soluna yazılan algoritmanın sonucunun sağa yazılan algoritma tarafından daha da sıkıştırıldığı anlamına gelir).
Gördüğünüz gibi, 80'lerin sonlarında - 90'ların başında geliştirilen ZIP, ARJ, RAR arşivleyicileri oldukça eski algoritmalar kullanıyor; bu nedenle, testler açısından daha modern olanlara kaybederler.

0 dereceli uyarlamalı sıkıştırma/açma programı örneği:

Veri: compr - sıkıştırılmış veriler burada saklanır
Veri - orijinal veriler burada saklanır
Frekans - sembollerin sıklığı

Prosedür kompres_aralığı; (Sıkıştırma prosedürü)
Var
cum_freq: Genişletilmiş;
Başlamak
(- Model ve kodlayıcı başlatma -)
q için: = 0 - 255 Yap
frekans [q]: = 1; (Başlangıçtaki tüm karakterler aynı olasılığa sahiptir)
frekans: = frekans - 0.20000;
toplam: = 256; (Tüm sembollerin frekanslarının toplamı.)
(Sıklıkta - 0 ve maksimum değerlerden küçük sapma)
PC: = 0; (Zaten kodlanmış bayt sayısı)
Lo: = 0; aralık: = 256;
(- Kodlama -)
q için: = 1 To Size Do
Başlamak
(Kodlanan karaktere karşılık gelen aralığı bulma)
cum_freq: = 0.1; (Olasılık biriktirmeye başlıyoruz)
w için: = 0 Veriye [q] - 1 Yap
cum_freq: = cum_freq + freq [w];
(Aralığı değiştir ve lo)
aralık: = aralık / toplam;
Lo: = Lo + aralık * (cum_freq);
aralık: = aralık * frekans];
(Normalleştirme, yani Lo ve Hi için aynı olan bayt çıktısı (Hi = Lo + Range))

Başlamak
Inc (PC);
compr: = Kes (Düşük);
Lo: = Frak (Lo) * 256;
aralık: = aralık * 256;
Son;
(Model Güncellemeleri)
sıklık]: = sıklık] + 1;
(Kodlanmış karakterin atanması 1 daha yüksek olasılık)
toplam: = toplam + 1;
Son;
(Sıkıştırma tamamlandı, kalan görüntüleniyor)
Lo: = Lo + aralık / 2;
Inc (PC);
compr: = Kes (Düşük);
Lo: = Frak (Lo) * 256;
aralık: = aralık * 256;
Son;

Prosedür decompress_range; (Prosedür açma)
Var
sıcaklık: Genişletilmiş;
ee: Genişletilmiş;
Başlamak
(Model ve kodlayıcı başlatma)
q için: = 0 - 255 Yap
frekans [q]: = 1;
frekans: = frekans - 0.20000; (Sıklıkta - 0 ve maksimum değerlerden küçük sapma)
toplam: = 256;
bilgisayar: = 4; (PC, okuduğumuz bayt sayısıdır)
kod: = 0;
Lo: = 0; aralık: = 256;
(Kodun ilk, yaklaşık değerini okuruz.)
q için: = 1'den 4'e Yap
Başlamak
kod: = kod * 256 + compr [q] / 65536/256;
Son;
w: = 0; (W, doğru şekilde açılmış bayt sayısıdır)
(Aslında açma)
doğru yaparken
Başlamak
(Bir sonraki karakterin olasılığını bulma)
sıcaklık: = (kod- Lo) * toplam / aralık;
(Sıcaklığın düştüğü bir karakter arayın)
toplam: = 0.1; toplam: = 0.1;
e için: = 0 - 255 Yap
Başlamak
toplam: = toplam + sıklık [e];
Toplam> temp ise Break;
ssum: = toplam;
Son;
Inc (w);
(Paketinin doğru açılıp açılmadığını kontrol etme)
(Şimdi e, paketlenmemiş bir bayttır ve bir dosyaya çıkarılabilir)
Eğer veri [w]<>e Sonra Ara; (Yanlış açılmışsa - çıkın)
Eğer w = Boyut O zaman Inc'e Başlayın (w); Ara Sonu; (Her şey paketlenmemişse, ayrılırız,)
(ve model güncellenmedi :-))
(Lo & Hi Güncellemeleri (Uzatma))
aralık: = aralık / toplam;
Lo: = Lo + aralık * (toplam);
aralık: = aralık * (frek [e]);
(Model güncellemesi (e'yi daha olası hale getirin))
frekans [e]: = frekans [e] + 1;
toplam: = toplam + 1;
(Normalleştirme, sayı iyileştirme)
Trunc (Lo) = Trunc (Lo + aralığı) iken
Başlamak
Inc (PC);
sıcaklık: = kompr;
kod: = (kod - trunc (kod)) * 256 + temp / 16777216;
Lo: = Frak (Lo) * 256;
aralık: = aralık * 256;
Son;
Son;
Aralık (g);
(DONE_DECOMPRESS)
Son;