Я шукаю алгоритм для стиснення невеликих текстових рядків: 50-1000 байт (тобто URL-адрес). Який алгоритм для цього найкраще працює?
tinyurls
чи щось пов’язане з місцем для зберігання?
Я шукаю алгоритм для стиснення невеликих текстових рядків: 50-1000 байт (тобто URL-адрес). Який алгоритм для цього найкраще працює?
tinyurls
чи щось пов’язане з місцем для зберігання?
Відповіді:
Перевірте Smaz :
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%
У Хаффмана є статична вартість, таблиця Хаффмана, тому я не погоджуюсь, що це вдалий вибір.
Існують адаптаційні версії, які цього не усувають, але швидкість стиснення може постраждати. Власне, питання, яке ви повинні задати, - це "який алгоритм для стиснення текстових рядків з цими характеристиками". Наприклад, якщо очікуються тривалі повтори, може бути достатньо простого кодування Run-Lengh. Якщо ви можете гарантувати, що будуть присутні лише англійські слова, пробіли, пунктуація та випадкові цифри, то Хаффман із заздалегідь визначеною таблицею Хаффмана може дати хороші результати.
Як правило, алгоритми сімейства Лемпель-Зів мають дуже гарну компресію та продуктивність, а бібліотек для них є в достатку. Я б з цим пішов.
З інформацією про те, що стискаються URL-адреси, я б запропонував, перш ніж стискати (за допомогою будь-якого алгоритму, який можна легко отримати), ви КОДУВАТИ їх. URL-адреси відповідають чітко визначеним шаблонам, і деякі його частини є передбачуваними. Використовуючи ці знання, ви можете зашифрувати URL-адреси на щось менше для початку, і ідеї, що стоять за кодуванням Хаффмана, можуть вам тут допомогти.
Наприклад, перекладаючи URL у потік бітів, ви можете замінити "http" на біт 1, а все інше на біт "0" з подальшим фактичним прокотолом (або використовувати таблицю для отримання інших загальних протоколів, таких як https, ftp, файл). ": //" можна взагалі відпустити, доки ви можете позначати кінець протоколу. Прочитайте про формат URL-адрес і подумайте, як їх можна кодифікувати, щоб зайняти менше місця.
У мене немає коду, але мені завжди подобався підхід до створення двовимірної таблиці пошуку розміром 256 * 256 символів ( RFC 1978 , протокол стиснення передбачувача PPP ). Щоб стиснути рядок, що переводиться циклом на кожну таблицю, і використовуйте таблицю пошуку, щоб отримати "передбачуваний" наступний знак, використовуючи поточний та попередній символи як індекси в таблиці. Якщо є відповідність, ви записуєте один 1 біт, інакше пишіть 0, char та оновлюйте таблицю пошуку поточною таблицею. Цей підхід в основному підтримує динамічну (і грубу) таблицю пошуку найбільш вірогідного наступного символу в потоці даних.
Ви можете почати з таблиці з нульовим пошуком, але при необхідності вона найкраще працює на дуже коротких рядках, якщо вона ініціалізована з найбільш ймовірним символом для кожної пари символів, наприклад, для англійської мови. Поки початкова таблиця пошуку однакова для стиснення та декомпресії, вам не потрібно передавати її в стиснуті дані.
Цей алгоритм не дає блискучого коефіцієнта стиснення, але він неймовірно ощадливий з ресурсами пам'яті та процесора, а також може працювати в безперервному потоці даних - декомпресор підтримує власну копію таблиці пошуку під час декомпресії, таким чином таблицю пошуку пристосовується до типу стиснених даних.
Будь-який алгоритм / бібліотека, яка підтримує заданий словник, наприклад zlib .
Таким чином, ви можете подати компресор із тим самим текстом, який, ймовірно, з’явиться на вході. Якщо файли якимось чином схожі (наприклад, всі URL-адреси, всі програми C, всі записи StackOverflow, всі графічні зображення ASCII), певні підрядки з’являться у більшості або всіх вхідних файлах.
Кожен алгоритм стиснення заощадить простір, якщо однакові підрядки повторюються кілька разів в одному вхідному файлі (наприклад, "the" в англійському тексті або "int" в коді C.)
Але у випадку URL-адрес певні рядки (наприклад, " http: // www .", ".Com", ".html", ".aspx" зазвичай з'являться один раз у кожному вхідному файлі. Тому вам потрібно поділитися ними між файлами якось замість того, щоб мати один стислий випадок у файлі. Якщо розмістити їх у встановленому словнику, це буде досягнуто цього.
Кодування Хаффмана в цілому працює нормально.
Якщо ви говорите про фактичне стискання тексту, а не просто скорочення, то 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
Ви можете поглянути на стандартну схему стиснення для Unicode .
SQL Server 2008 R2 використовує його внутрішньо і може досягти стиснення до 50%.