Гольфінг Струни


22

Мені завжди не вдалося дати відповідь на які вимагають стиснення рядків, головна причина в тому, що я не знаю використовувати інструменти для стиснення рядків так само ефективно, як слід .

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

Отже, як я можу використовувати інструменти стискання рядків для їх максимальної ефективності?

Відповіді:


9

Базова конверсія (CJam)

Найпростішим способом кодування рядків ASCII, які не починаються з нульового байта, є перетворення з бази 128 в ціле число, а потім в базу 256:

128b256b:c              e# Prints encoded string.
128b256b:c`"256b128b:c" e# Prints encoded string with decoder.

Для кодування кожного символу ASCII використовується 7 біт.

Якщо вихідна рядок складається тільки з, наприклад, малі літери, і не робить старт з а , ми можемо почати відображення "a...z"на [0 ... 25], а потім продовжуйте , як вказано вище:

'afm26b256b:c               e# Prints encoded string.
'afm26b256b:c`"256b26b'af+" e# Prints encoded string with decoder.

Нарешті, якщо початковий рядок містить лише декілька унікальних символів (поширених у мистецтві ASCII), зазвичай краще чітко вказати алфавіт.

Наприклад:

" +-/\|"f#6b256b:c                       e# Prints encoded string.
" +-/\|"f#6b256b:c`"256b6b"" +-/\|"`"f=" e# Prints encoded string with decoder.

Як правило, ви хочете, щоб перший символ початкового рядка був другим символом алфавіту, наступний виразний символ початкового рядка був першим символом алфавіту, наступним чітким символом початкового рядка є бути третім символом алфавіту, наступним виразним символом початкового рядка буде четвертий символ алфавіту тощо.

Кодер останнього прикладу працює наступним чином:

" +-/\|"f# e# Replace each character by its index in that string.
6b256b     e# Convert from base 6 (length of the alphabet) to base 256.
:c         e# Cast each digit to character.

Декодер останнього прикладу працює наступним чином:

256b6b     e# Convert from base 256 to base 6.
" +-/\|"f= e# Replace each digit by the corresponding character of the alphabet.

2
Я був би більш конкретним: як правило, ви хочете, щоб перший символ початкового рядка був другим символом алфавіту, а наступний виразний символ початкового рядка був першим символом алфавіту, ...
Пітер Тейлор

@PeterTaylor Додано Спасибі!
Денніс

9

Питання складності Колмогорова з деякою структурою, але не проста формула (наприклад, пісня пісні), як правило, виграє від граматичного підходу. По суті, ви витягуєте повторні підрядки і якось кодуєте їх. Це робить Лемпель-Зів, використовуючи досить обмежений клас граматик; якщо ви використовуєте більш загальні граматики, тоді ви повинні з'ясувати, як кодувати правила. Наприклад , один підхід тут «зсув кодування», де зсув кожного вихідний байта за кількістю правил ( n), призначте байти 1до nправил, використовувати 0байти в окремі правила, і повторно замінити байти iз оцінюваним правилом i. Нарешті ви скасовуєте зміщення, віднімаючи nз кожного байта.

Я фактично написав програму Java, яка реалізує різні підходи:

Більшість підходів дотримуються двофазного процесу. На першій фазі рядок перетворюється на граматику, яка її генерує; на другій фазі граматика перетворюється на програму GolfScript. Реалізація на першому етапі багато в чому базується на Charikar, Lehman, Liu, Panigrahy, Prabhakaran, Sahai, & Shelat (2005) Найменша граматична проблема , Теорія інформації, IEEE Transaction on, 51 (7), 2554-2576.

Він також включає підхід Lempel-Ziv, базовий підхід до кодування та підхід кодування довжини, що визначає довжину, і визначає той, який дає найкоротшу програму.


0

Стакс

У Stax мовою код гри в гольф, є корисний інструмент трохи називається строковий літерал компресора . Я не знаю , як це працює, точно, але є інший , де я дійсно знаю , як це працює. Він перетворює рядки в числа, потім у Base 256. Це CP437 , з 0x00 та 0xFF, перетвореними для копіювання. Це PackedStax. Ви можете конвертувати свої струни за допомогою рядкового компресорного рядка, а потім упакувати його для гарного стиснення.

Використовуючи цей процес, рядок "Цей рядок становить тридцять два байти" може бути перетворений у v * "A] - | W4]} 3"% (стислий рядок, як правило, оточений зворотними посиланнями, щоб визначити різницю між звичайною рядком в Stax ) і нарешті до üvìë! [┴╩qJu ← ▓α для стиснення / зменшення на 18 байт, більше половини.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.