Ефективний алгоритм стиснення для коротких текстових рядків [закритий]


126

Я шукаю алгоритм для стиснення невеликих текстових рядків: 50-1000 байт (тобто URL-адрес). Який алгоритм для цього найкраще працює?


1
Де ви хочете використовувати ці стислі рядки?
Gumbo

1
Це йде назустріч tinyurlsчи щось пов’язане з місцем для зберігання?
nik

6
Мене цікавить алгоритм стиснення URL-адрес, найкращий коефіцієнт стиснення важливіший, ніж поточна вартість. Не цікавить Інтернет-сервіси, такі як tinyurls або tr.im. Я шукаю алгоритм, а не сервіс. Не думаю, що будь-яка інша інформація може бути корисною ...
Василь Корольов

3
@Gumbo: "Алгоритмів стиснення тексту для коротких рядків" достатньо для пошуку альго, чому ви так зацікавлені дізнатися, для чого вони призначені? Я впевнений, що ОП зможе знайти того, хто робить те, що хоче.
Дервін Тунк

7
@Василія, невеличкий натяк: Щоразу, коли ви ставите запитання щодо SO у формі "Що найкраще XYZ?", Ваше запитання майже неодмінно отримає голоси за закриття, оскільки прохання про найкраще може призвести до непотрібного продукту порівняння, або, в гіршому випадку, навіть полум’яні війни. (Зазвичай це вимагає лише дуже невеликих змін, щоб уникнути цього. Якщо ви задали те саме запитання, як, наприклад, "Будь ласка, запропонуйте XYZ.", Ви б не отримали стільки голосів, що закриваються, хоча це в основному те саме питання!)
stakx - більше не вносять внесок

Відповіді:


62

Перевірте Smaz :

Smaz - це проста бібліотека стиснення, яка підходить для стиснення дуже коротких рядків.


17
Дивіться github.com/antirez/smaz/blob/master/smaz.c - це варіант кодування, а не стиснення як такого (принаймні, не повністю). Він використовує статичний словник і слова з літер.
Рой Тінкер

7
Примітка. Це проект антирезу. Він є одним з головних авторів Redis і має дуже сильну репутацію, випускаючи високоякісний, виробничий код.
Homer6

7
Алгоритм smaz оптимізований для англійських текстів, тому не працює добре для випадкових рядків. Ось деякі зразки ( 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
Також подивіться на меншу компресію, але швидкий алгоритм shoco ed-von-schleck.github.io/shoco
Dickey Singh

Додати мою бібліотеку Unishox до списку github.com/siara-cc/unishox . Він краще, ніж Smaz і Shoco і підтримує стиснення струн UTF-8.
арунь

28

У Хаффмана є статична вартість, таблиця Хаффмана, тому я не погоджуюсь, що це вдалий вибір.

Існують адаптаційні версії, які цього не усувають, але швидкість стиснення може постраждати. Власне, питання, яке ви повинні задати, - це "який алгоритм для стиснення текстових рядків з цими характеристиками". Наприклад, якщо очікуються тривалі повтори, може бути достатньо простого кодування Run-Lengh. Якщо ви можете гарантувати, що будуть присутні лише англійські слова, пробіли, пунктуація та випадкові цифри, то Хаффман із заздалегідь визначеною таблицею Хаффмана може дати хороші результати.

Як правило, алгоритми сімейства Лемпель-Зів мають дуже гарну компресію та продуктивність, а бібліотек для них є в достатку. Я б з цим пішов.

З інформацією про те, що стискаються URL-адреси, я б запропонував, перш ніж стискати (за допомогою будь-якого алгоритму, який можна легко отримати), ви КОДУВАТИ їх. URL-адреси відповідають чітко визначеним шаблонам, і деякі його частини є передбачуваними. Використовуючи ці знання, ви можете зашифрувати URL-адреси на щось менше для початку, і ідеї, що стоять за кодуванням Хаффмана, можуть вам тут допомогти.

Наприклад, перекладаючи URL у потік бітів, ви можете замінити "http" на біт 1, а все інше на біт "0" з подальшим фактичним прокотолом (або використовувати таблицю для отримання інших загальних протоколів, таких як https, ftp, файл). ": //" можна взагалі відпустити, доки ви можете позначати кінець протоколу. Прочитайте про формат URL-адрес і подумайте, як їх можна кодифікувати, щоб зайняти менше місця.


4
Не, якщо таблиця huffman однакова для всіх файлів, що мало б сенс, якщо всі файли схожі між собою.
finnw

1
Якщо у вас багато, схожих, невеликих файлів, ви все робите неправильно. Спочатку з'єднайте їх усіх (як дьоготь), а потім стисніть. Ви отримаєте кращу компресію, і проблема перестане бути "50-1000 байт".
Даніель К. Собрал

8
@Daniel: залежить від того, чи хочете ви довільний доступ до стислих даних. Стиснення всього цього запобігає цьому у більшості систем стиснення.
Стів Джессоп

22

У мене немає коду, але мені завжди подобався підхід до створення двовимірної таблиці пошуку розміром 256 * 256 символів ( RFC 1978 , протокол стиснення передбачувача PPP ). Щоб стиснути рядок, що переводиться циклом на кожну таблицю, і використовуйте таблицю пошуку, щоб отримати "передбачуваний" наступний знак, використовуючи поточний та попередній символи як індекси в таблиці. Якщо є відповідність, ви записуєте один 1 біт, інакше пишіть 0, char та оновлюйте таблицю пошуку поточною таблицею. Цей підхід в основному підтримує динамічну (і грубу) таблицю пошуку найбільш вірогідного наступного символу в потоці даних.

Ви можете почати з таблиці з нульовим пошуком, але при необхідності вона найкраще працює на дуже коротких рядках, якщо вона ініціалізована з найбільш ймовірним символом для кожної пари символів, наприклад, для англійської мови. Поки початкова таблиця пошуку однакова для стиснення та декомпресії, вам не потрібно передавати її в стиснуті дані.

Цей алгоритм не дає блискучого коефіцієнта стиснення, але він неймовірно ощадливий з ресурсами пам'яті та процесора, а також може працювати в безперервному потоці даних - декомпресор підтримує власну копію таблиці пошуку під час декомпресії, таким чином таблицю пошуку пристосовується до типу стиснених даних.


Але як би поводився предиктор з нормальним англійським реченням? Наведений приклад має дуже сильну надмірність, а посилення мінімальне.
Дунайський матрос

Таблиця пошуку 256 * 256 не звучить "неймовірно скромно з пам'яттю" ...!
MikeW

@MikeW Ну це 65 кілобайт.
redcalx

@redcalx Якби це було 65 байт, я б, можливо, погодився!
MikeW

11

Будь-який алгоритм / бібліотека, яка підтримує заданий словник, наприклад zlib .

Таким чином, ви можете подати компресор із тим самим текстом, який, ймовірно, з’явиться на вході. Якщо файли якимось чином схожі (наприклад, всі URL-адреси, всі програми C, всі записи StackOverflow, всі графічні зображення ASCII), певні підрядки з’являться у більшості або всіх вхідних файлах.

Кожен алгоритм стиснення заощадить простір, якщо однакові підрядки повторюються кілька разів в одному вхідному файлі (наприклад, "the" в англійському тексті або "int" в коді C.)

Але у випадку URL-адрес певні рядки (наприклад, " http: // www .", ".Com", ".html", ".aspx" зазвичай з'являться один раз у кожному вхідному файлі. Тому вам потрібно поділитися ними між файлами якось замість того, щоб мати один стислий випадок у файлі. Якщо розмістити їх у встановленому словнику, це буде досягнуто цього.


2
Поради щодо користувальницького словника: stackoverflow.com/questions/2011653
Trenton


4

Якщо ви говорите про фактичне стискання тексту, а не просто скорочення, то Deflate / gzip (обгортка навколо gzip), zip добре працює для менших файлів та тексту. Інші алгоритми дуже ефективні для великих файлів, таких як bzip2 і т.д.

У Вікіпедії є список разів стиснення. (шукайте для порівняння ефективності)

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

6
Він хоче стискати текст, а не файли.
Gumbo

3
За допомогою цих алгоритмів ви можете стискати текст і двійкові файли. Насправді ми використовуємо дефляцію в системі cms, яка працює в python.
Райан Крістенсен

Приклад в C # за допомогою gzip для рядків є тут: csharphelp.com/archives4/archive689.html
Ryan Christensen

модуль zlib в python для стискання струн: python.org/doc/2.5.2/lib/module-zlib.html
Ryan Christensen

3
gzip (і zlib) використовує дефляцію та додає обгортку / обрамлення накладних витрат. Пряме дефляцію / LZ77 (словникові накладні витрати та ефективність все ще залежить від реалізації таких параметрів та параметрів) може зменшити беззбитковість накладних витрат. Це, звичайно, для "коротких" рядків у десятках до сотень символів (все ж має бути трохи вказівки "чи було це стиснуто", щоб уникнути збільшення даних). Збільшення додаткових накладних витрат не має значення .. оскільки текст збільшується. Номери, розміщені тут, здаються, для великих текстових файлів (багато секунд, щоб запустити!), Тоді як ОП вимагає 50-1000 статутів - дуже малі порівняно.
користувач2864740

2

Ви можете поглянути на стандартну схему стиснення для Unicode .

SQL Server 2008 R2 використовує його внутрішньо і може досягти стиснення до 50%.


SCSU 'стискає' не англійський Unicode в кодуванні UTF-16 / MB. Якщо Unicode / звичайний-старий-ASCII на базі англійської мови, UTF-8 також "стискає" 50% UTF-16 ..
user2864740
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.