Algoritma kompresi yang efisien untuk string teks pendek [tertutup]

126

Saya mencari algoritme untuk mengompresi string teks kecil: 50-1000 byte (yaitu URL). Algoritma mana yang paling cocok untuk ini?

Dengan mudah Korolev
sumber
1
Di mana Anda ingin menggunakan string terkompresi ini?
Gumbo
1
Apakah ini mengarah tinyurlsatau ada hubungannya dengan ruang penyimpanan?
nik
6
Saya tertarik pada algoritma untuk mengompresi URL, rasio kompresi terbaik lebih penting daripada menjalankan biaya. Tidak tertarik dengan layanan online seperti tinyurl atau tr.im. Saya mencari algoritma bukan layanan. Jangan berpikir info lain bisa berguna ...
Vasily Korolev
3
@ Gumbo: "Algoritma kompresi teks untuk string pendek" sudah cukup untuk menemukan algo, mengapa Anda begitu tertarik untuk mengetahui apa gunanya? Saya yakin OP akan dapat menemukan yang melakukan apa yang diinginkannya.
Dervin Thunk
7
@ Mudah, petunjuk kecil: Setiap kali Anda mengajukan pertanyaan pada SO dalam bentuk, "Apa XYZ terbaik ?", Pertanyaan Anda hampir pasti akan menerima suara untuk ditutup karena meminta yang terbaik mungkin mengarah ke produk yang tidak perlu perbandingan, atau dalam kasus terburuk, bahkan perang api. (Biasanya hanya dibutuhkan perubahan yang sangat kecil untuk menghindari hal itu: Jika Anda mengajukan pertanyaan yang sama seperti, "Tolong sarankan XYZ.", Anda tidak akan mendapatkan banyak suara penutup, meskipun pada dasarnya pertanyaan yang sama!)
stakx - tidak lagi berkontribusi

Jawaban:

62

Lihat Smaz :

Smaz adalah pustaka kompresi sederhana yang cocok untuk mengompresi string yang sangat pendek.

stvchu
sumber
17
Lihat github.com/antirez/smaz/blob/master/smaz.c - ini adalah varian dari pengkodean, bukan kompresi per se (setidaknya tidak seluruhnya). Dia menggunakan kamus kata dan huruf statis.
Roy Tinker
7
Catatan: Ini adalah proyek antirez. Dia adalah salah satu penulis utama Redis dan memiliki reputasi yang sangat kuat dalam mengeluarkan kode produksi berkualitas tinggi.
Homer6
7
Algoritma smaz dioptimalkan untuk teks bahasa Inggris, oleh karena itu tidak berfungsi dengan baik untuk string acak. Berikut adalah beberapa sampel ( string:orig_size:compr_size:space_savings): This is the very end of it.:27:13:52%, Lorem ipsum dolor sit amet:26:19:27%, Llanfairpwllgwyngyll:20:17:15%, aaaaaaaaaaaaa:13:13:0%, 2BTWm6WcK9AqTU:14:20:-43%,XXX:3:5:-67%
mykhal
4
Lihat juga kompresi yang lebih rendah tetapi algoritma cepat shoco ed-von-schleck.github.io/shoco
Dickey Singh
Tambahkan perpustakaan saya Unishox ke daftar github.com/siara-cc/unishox . Berkinerja lebih baik daripada Smaz dan Shoco dan mendukung kompresi string UTF-8.
arun
28

Huffman memiliki biaya statis, tabel Huffman, jadi saya tidak setuju itu pilihan yang baik.

Ada versi adaptasi yang menghilangkan ini, tetapi tingkat kompresi mungkin menderita. Sebenarnya, pertanyaan yang harus Anda tanyakan adalah "algoritma apa untuk memampatkan string teks dengan karakteristik ini". Misalnya, jika pengulangan panjang diharapkan, Pengodean Run-Lengh sederhana mungkin sudah cukup. Jika Anda dapat menjamin bahwa hanya kata-kata bahasa Inggris, spasi, tanda baca dan angka sesekali akan hadir, maka Huffman dengan tabel Huffman yang telah ditentukan sebelumnya dapat memberikan hasil yang baik.

Secara umum, algoritma dari keluarga Lempel-Ziv memiliki kompresi dan kinerja yang sangat baik, dan perpustakaan untuk mereka berlimpah. Saya akan pergi dengan itu.

Dengan informasi bahwa apa yang dikompresi adalah URL, maka saya akan menyarankan itu, sebelum mengompresi (dengan algoritma apa pun yang mudah tersedia), Anda CODIFY mereka. URL mengikuti pola yang jelas, dan beberapa bagiannya sangat mudah diprediksi. Dengan memanfaatkan pengetahuan ini, Anda dapat menyusun URL menjadi sesuatu yang lebih kecil untuk memulai, dan ide-ide di balik penyandian Huffman dapat membantu Anda di sini.

Misalnya, menerjemahkan URL ke bit stream, Anda dapat mengganti "http" dengan bit 1, dan apa pun dengan bit "0" diikuti oleh procotol yang sebenarnya (atau menggunakan tabel untuk mendapatkan protokol umum lainnya, seperti https, ftp, file). Tanda ": //" dapat dihapus seluruhnya, selama Anda dapat menandai akhir dari protokol. Dll. Baca tentang format URL, dan pikirkan bagaimana mereka dapat dikodifikasikan untuk menghemat ruang.

Daniel C. Sobral
sumber
4
Tidak jika tabel huffman sama untuk semua file, yang akan masuk akal jika semua file mirip satu sama lain.
finnw
1
Jika Anda memiliki banyak, mirip, file kecil, Anda melakukan semuanya salah. Pertama, gabungkan semuanya (seperti tar), lalu kompres. Anda akan mendapatkan kompresi yang lebih baik, dan masalahnya tidak lagi menjadi "50-1000 byte".
Daniel C. Sobral
8
@Aniel: tergantung apakah Anda ingin akses acak ke data yang dikompresi. Mengompresi semuanya bersama-sama mencegahnya dengan sebagian besar sistem kompresi.
Steve Jessop
22

Saya tidak punya kode, tapi saya selalu menyukai pendekatan membangun tabel pencarian 2D ukuran 256 * 256 karakter ( RFC 1978 , PPP Predictor Compression Protocol ). Untuk mengompres string, Anda mengulangi masing-masing karakter dan menggunakan tabel pencarian untuk mendapatkan karakter berikutnya yang 'diprediksi' menggunakan karakter saat ini dan sebelumnya sebagai indeks ke dalam tabel. Jika ada kecocokan yang Anda tuliskan 1 bit, jika tidak tulis 0, char dan perbarui tabel pencarian dengan char saat ini. Pendekatan ini pada dasarnya mempertahankan tabel pencarian dinamis (dan mentah) dari karakter berikutnya yang paling mungkin dalam aliran data.

Anda bisa mulai dengan tabel looked yang memusatkan perhatian, tetapi jelas itu bekerja paling baik pada string yang sangat pendek jika diinisialisasi dengan karakter yang paling mungkin untuk setiap pasangan karakter, misalnya, untuk bahasa Inggris. Selama tabel pencarian awal sama untuk kompresi dan dekompresi Anda tidak perlu memancarkannya ke dalam data terkompresi.

Algoritme ini tidak memberikan rasio kompresi yang brilian, tetapi sangat hemat dengan memori dan sumber daya CPU dan juga dapat bekerja pada aliran data yang berkelanjutan - dekompresor menyimpan salinan tabel pencarian sendiri saat terdekompresi, sehingga tabel pencarian menyesuaikan dengan tipe data yang dikompresi.

redcalx
sumber
Tetapi bagaimana prediktor akan berperilaku dengan kalimat bahasa Inggris yang normal? Contoh yang diberikan memiliki redundansi yang sangat kuat, dan keuntungannya minimal.
Danubian Sailor
Tabel pencarian 256 * 256 tidak terdengar "sangat hemat dengan memori" ...!
MikeW
@ MikeW Yah, itu 65 kilobyte.
redcalx
@redcalx Jika sudah 65 byte saya mungkin setuju!
MikeW
11

Algoritma / pustaka apa pun yang mendukung kamus preset, mis . Zlib .

Dengan cara ini Anda dapat menggunakan kompresor dengan jenis teks yang sama yang kemungkinan akan muncul di input. Jika file serupa dalam beberapa cara (misalnya semua URL, semua program C, semua posting StackOverflow, semua gambar ASCII-art) maka substring tertentu akan muncul di sebagian besar atau semua file input.

Setiap algoritma kompresi akan menghemat ruang jika substring yang sama diulang beberapa kali dalam satu file input (misalnya "the" dalam teks bahasa Inggris atau "int" dalam kode C.)

Tetapi dalam kasus URL string tertentu (misalnya " http: // www .", ".Com", ".html", ".aspx" biasanya akan muncul satu kali di setiap file input. Jadi, Anda perlu membaginya di antara file entah bagaimana daripada memiliki satu kejadian terkompresi per file. Menempatkan mereka dalam kamus yang telah ditetapkan akan mencapai ini.

menemukan
sumber
2
Kiat menggunakan kamus khusus: stackoverflow.com/questions/2011653
Trenton
4

Pengodean Huffman umumnya berfungsi baik untuk ini.

Zifre
sumber
4
Ini bukan jawaban hanya tautan; tanpa tautan, itu masih merupakan jawaban yang valid.
SL Barth - Pasang kembali Monica
..dan masih bukan jawaban yang bagus. (Tidak cukup informasi yang relevan dibawa.)
user2864740
4

Jika Anda berbicara tentang mengompres teks tidak hanya memperpendek lalu Mengempis / gzip (membungkus gzip), zip berfungsi dengan baik untuk file dan teks yang lebih kecil. Algoritma lain sangat efisien untuk file yang lebih besar seperti bzip2 dll.

Wikipedia memiliki daftar waktu kompresi. (cari perbandingan efisiensi)

Name       | Text         | Binaries      | Raw images
-----------+--------------+---------------+-------------
7-zip      | 19% in 18.8s | 27% in  59.6s | 50% in 36.4s
bzip2      | 20% in  4.7s | 37% in  32.8s | 51% in 20.0s
rar (2.01) | 23% in 30.0s | 36% in 275.4s | 58% in 52.7s
advzip     | 24% in 21.1s | 37% in  70.6s | 57& in 41.6s
gzip       | 25% in  4.2s | 39% in  23.1s | 60% in  5.4s
zip        | 25% in  4.3s | 39% in  23.3s | 60% in  5.7s
Ryan Christensen
sumber
6
Dia ingin mengompres teks dan bukan file.
Gumbo
3
Anda dapat mengompresi teks dan binari dengan algoritma ini. Bahkan kami menggunakan deflate dalam sistem cms yang berjalan di python.
Ryan Christensen
Contoh dalam C # menggunakan gzip untuk string ada di sini: csharphelp.com/archives4/archive689.html
Ryan Christensen
zlib module in python untuk mengompresi string: python.org/doc/2.5.2/lib/module-zlib.html
Ryan Christensen
3
gzip (dan zlib) menggunakan deflate dan menambahkan overhead wrapper / framing .. direct deflate / LZ77 (overhead kamus dan efisiensi masih tergantung pada implementasi seperti itu dan pengaturan) dapat mengurangi overhead impas. Ini untuk string "pendek" dalam lusinan hingga ratusan karakter, tentu saja (masih harus memiliki sedikit untuk menunjukkan "apakah ini dikompresi"? Untuk menghindari memperbesar data). Overhead tambahan yang lebih besar tidak masalah .. karena teks meningkat. Angka-angka yang diposting di sini tampaknya untuk file teks besar (beberapa detik untuk menjalankan!), Sementara OP meminta 50-1000 charter - sangat kecil jika dibandingkan.
user2864740
2

Anda mungkin ingin melihat Skema Kompresi Standar untuk Unicode .

SQL Server 2008 R2 menggunakannya secara internal dan dapat mencapai kompresi hingga 50%.

Le Hibou
sumber
SCSU 'mengkompres' Unicode non-Inggris dalam pengkodean UTF-16 / MB. Jika Unicode berbasis bahasa Inggris / plain-old-ASCII, UTF-8 juga 'memampatkan' 50% UTF-16 ..
user2864740