2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




На страницу 1, 2  След.
 
 RLE(Run Lenght Encoding) реализация!
Сообщение20.02.2008, 05:16 
Здравствуйте!
Самый простой и очевидный метод сжатия – RLE (Run Length Encoding) – кодирование повторяющихся последовательностей символов. Суть его в замене последовательности одинаковых символов во входном потоке флагом (признаком) кодированных данных, символом и количеством его повторений в выходном потоке.
в общем требуется помошь в реализации на делфи или на паскале алгоритма сжатия RLE .с чего начать?я думаю нужно на вход подавать текстовый файл с цепочкой символов (например, 3333еееееррррввв777йййй),а на выход файл (закодированый файл в своём формате,нпример .rle),нужно также реализовать функцию раскодирования.
помогите разобраться как правильно сделать кодировщик для начала

 
 
 
 
Сообщение20.02.2008, 05:32 
Аватара пользователя
:evil:
Walt Disney писал(а):
с чего начать?

Я думаю, неплохо начать с того, какой выход должен быть у такой программы. Например, вход
Код:
3333еееееррррввв777йййй
, выход
Код:
(3, 4), (е, 5), (р, 4), (в, 3), (7, 3), (й, 4)


После этого можно решить, как представить такой выход в файле. Ну а дальше совсем просто, не правда ли?

 
 
 
 
Сообщение20.02.2008, 07:04 
неправда:)если опыт программирования маленький,а насчёт выхода спасибо за идею,а с помощью чего это реализуется?массив?

 
 
 
 
Сообщение20.02.2008, 09:28 
Аватара пользователя
Никаких массивов не надо. Просто в цикле считываем из файла символ за символом. Во внутренних переменных запоминаем последний считанный символ и количество раз, сколько он встретился подряд. Когда на вход поступает очередной символ, то сравниваем его с сохраненным. Если совпадает, то увеличиваем на 1 счетчик и ничего больше не делаем. Если не совпадает, то выводим в выходной файл в выбранном формате информацию о предыдущем блоке и начинаем запоминать новый блок.

 
 
 
 
Сообщение20.02.2008, 21:12 
Аватара пользователя
:evil:
PAV писал(а):
Если совпадает, то увеличиваем на 1 счетчик и ничего больше не делаем.

Ну, вообще говоря, делаем. Дело в том, что на счётчик в выходном файле отводится конечное число разрядов, например 8. В этом случае попытка вывести счётчик 300 приведёт к ошибке. Поэтому, когда счётчик становится больше максимального, надо вытолкнуть максимальное повторение в выход и начать сначала.

PAV писал(а):
Если не совпадает, то выводим в выходной файл в выбранном формате информацию о предыдущем блоке и начинаем запоминать новый блок.

И не забыть вытолкнуть в файл последнюю группу.

~~~

Есть интересный нюанс: счётчики всегда больше нуля. Этим часто пользуются, запоминая в файле счётчик -1, и, таким образом, немного увеличивая максимальную группу.

 
 
 
 
Сообщение20.02.2008, 21:21 
Аватара пользователя
незваный гость писал(а):
И не забыть вытолкнуть в файл последнюю группу.


Я бы это сделал в самом цикле. Условие вывода в файл = (конец файла) ИЛИ (несовпадение символов) ИЛИ (переполнение счетчика).

Добавлено спустя 2 минуты:

На самом деле, если уж уточнять все детали, то нужно аккуратно расписать начало работы цикла, когда на вход подается первый символ. В этом случае еще ничего в выходной файл выводить не нужно.

 
 
 
 
Сообщение20.02.2008, 23:48 
Аватара пользователя
:evil:
PAV писал(а):
Я бы это сделал в самом цикле. Условие вывода в файл = (конец файла) ИЛИ (несовпадение символов) ИЛИ (переполнение счетчика).

Это разница между математиком и программистом: программист экономит число проверок, а математик — борется за простоту программы :)

 
 
 
 
Сообщение21.02.2008, 09:24 
Аватара пользователя
Но нам же все равно внутри цикла придется хоть раз проверять, не закончился ли файл. Так что мне кажется, что у меня ничего лишнего не делается :?:

 
 
 
 
Сообщение21.02.2008, 11:24 
Аватара пользователя
Wikipedia писал(а):
Кодирование повторов — это очень простой алгоритм сжатия данных, который оперирует сериями данных, то есть последовательностями, в которых один и тот же символ встречается несколько раз подряд. При кодировании строка одинаковых символов, составляющих серию, заменяется строкой, которая содержит сам повторяющийся символ и количество его повторов.

Рассмотрим изображение, содержащий простой чёрный текст на сплошном белом фоне. Здесь будет много серий белых пикселей в пустых местах, и много коротких серий чёрных пикселей в тексте. В качестве примера приведена некая произвольная строка изображения в черно-белом варианте. Здесь B представляет чёрный пиксель, а W обозначает белый:

WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW

Если мы применим простое кодирование длин серий к этой строке, то получим следующее:

12WB12W3B24WB14W

Последняя запись интерпретируется как "двенадцать W", "одна B", "двенадцать W", "три B" и т. д. Таким образом, код представляет исходные 67 символов в виде всего лишь 16.

Конечно, кодирование, которое используется для хранения изображений, оперирует с двоичными данными, а не с символами ASCII, как в рассмотренном примере, однако принцип остаётся тот же.


вот в связи с этим возник вопрос, а как быть со сторокой 3333еееееррррввв777йййй
если кодировать именно так, как предложено в вики, то получим 435е4р3в374й, что не совсем то, что хотелось бы, поскольку обратное преобразование даст не то, что было изначально

 
 
 
 
Сообщение21.02.2008, 12:36 
photon писал(а):
вот в связи с этим возник вопрос, а как быть со сторокой 3333еееееррррввв777йййй
если кодировать именно так, как предложено в вики, то получим 435е4р3в374й, что не совсем то, что хотелось бы, поскольку обратное преобразование даст не то, что было изначально

В Википедии описан принцип. Детали реализации - дело второе. Необходимо введение ключевого символа, или еще какие ухищрения, естественно.

 
 
 
 
Сообщение21.02.2008, 12:38 
Аватара пользователя
Просто я подумал, что основной принцип уже уловили и начали обсуждать детали (реализация циклов, проверка условий), поэтому и поднял вопрос о конкретной форме записи выходного результата.

 
 
 
 
Сообщение21.02.2008, 13:03 
Аватара пользователя
Мне кажется, что будет правильно, если автор вопроса сам продумает детали реализации, а также понаступает на возникающие при этом грабли. Это полезно, если хочешь научиться. Тем более, что он куда-то пропал...

 
 
 
 
Сообщение26.02.2008, 13:00 
не куда я не пропал,я тут:)простоне совсем понятен сам алгоритм с циклом?а что использовать в качестве флага?например если такая последовательность 22226666333кодируется в 424633 как его раскодировать тогда?нужно выделять отдельно память под счётчик?

 
 
 
 
Сообщение26.02.2008, 13:29 
Аватара пользователя
Это уже вопросы выбора формата. Простыми способами являются либо использование некоторого фиксированного символа в виде разделителя (при этом количество повторов может занимать переменное число разрядов), либо строго зафиксировать это число разрядов.

Walt Disney писал(а):
нужно выделять отдельно память под счётчик?

Этого вопроса я не понял.

 
 
 
 
Сообщение27.02.2008, 07:19 
Аватара пользователя
:evil:
Walt Disney писал(а):
а что использовать в качестве флага?например если такая последовательность 22226666333кодируется в 424633 как его раскодировать тогда

незваный гость уже писал(а):
После этого можно решить, как представить такой выход в файле.

В принципе, вариантов-то много. Все и не перечислить — фиксированная разрядность, маркеры, разнообразное кодирование длины счётчика…

Самый первый выбор, который Вы должны сделать — это является ли выходной файл текстовым или двоичным.

 
 
 [ Сообщений: 16 ]  На страницу 1, 2  След.


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group