Гольф Стрингс

22

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

По этой причине я разместил этот вопрос. В отличие от моих других вопросов о советах, это не зависит от языка, что означает, что если вы можете придумать какие-либо советы на своем родном языке, вы можете опубликовать их (при условии, что вы укажете язык). Общие советы также приветствуются.

Итак, как я могу использовать инструменты сжатия строк для их максимальной эффективности?

Бета распад
источник

Ответы:

9

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

Простой способ кодировать строки ASCII, которые не начинаются с нулевого байта, - это преобразовать из базы 128 в целое число, а затем в базу 256:

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

Это использует 7 бит для кодирования каждого символа ASCII.

Если исходная строка состоит только из, например, строчные буквы, и не делает старт с а , мы можем начать отображение "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. Реализации первого этапа в значительной степени основаны на Чарикаре, Лемане, Лю, Паниграхи, Прабхакаране, Сахае и Шелате (2005) . Наименьшая проблема грамматики , Теория информации, IEEE Transactions, 51 (7), 2554-2576.

Он также включает в себя подход Лемпеля-Зива, подход базового кодирования и подход кодирования длин серий и идентифицирует тот, который дает самую короткую программу.

Питер Тейлор
источник
0

Stax

На языке гольфа Stax code есть полезный небольшой инструмент, называемый компрессором строковых литералов . Я не знаю , как это работает, точно, но есть другой , где я действительно знаю , как это работает. Он преобразует строки в числа, а затем в базу 256. Это CP437 , с 0x00 и 0xFF, преобразованными для копирования. Это PackedStax. Вы можете преобразовать свои строки с помощью строкового литерального компрессора, а затем упаковать его для хорошего сжатия.

Используя этот процесс, строку «Эта строка составляет тридцать два байта» можно преобразовать в v * "A] - | W4]} 3"% (сжатая строка обычно окружена обратными чертами, чтобы указать разницу между обычной строкой в ​​Stax ) и, наконец, üvìë! [┴╩qJu ← forα для сжатия / уменьшения 18 байт, более половины.

Итан Слота
источник