Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 19.05.2024, 14:00   #1
Kronos913
Форумчанин
 
Регистрация: 10.02.2021
Сообщений: 640
По умолчанию Простое сжатие текста

Какие есть простые алгоритмы сжатия текста?

Лично мне на ум пришло только вот что:
Символы от #1 до #31 почти не используются в текстах, а #13 и #10 всегда стоят в паре
И на все не используемые символы назначить популярные сочетания 2-3 букв, или сразу слова

Есть ли какие-то еще простые алгоритмы? Так чтобы дешифратор занимал не более 1 экрана кода, может 2 максимум?

И сразу вопрос, есть ли какой-то более адекватный способ посимвольного заполнения строки, чем
s:=s+c где s - string а c - добавляемый char
Kronos913 вне форума Ответить с цитированием
Старый 19.05.2024, 15:29   #2
Vapaamies
Ваш К. О.
Участник клуба
 
Аватар для Vapaamies
 
Регистрация: 26.12.2012
Сообщений: 1,799
По умолчанию

Цитата:
Сообщение от Kronos913 Посмотреть сообщение
Какие есть простые алгоритмы сжатия текста?
А вам зачем? Мы покупаем или продаем? В общем случае внутрипрограммное сжатие — не та тема, которой нужно заниматься. Если же очень хочется нужно, все допустимые случаи проходят как особые и на 99,9% ограничиваются лишь собственным форматом данных — файла или потока, само же сжатие и распаковка выполняются вызовом готовых реализаций/библиотек. Пример — Git.

Цитата:
Сообщение от Kronos913 Посмотреть сообщение
Символы от #1 до #31 почти не используются в текстах
На этом принципе (в числе прочих) основан алгоритм BOCU. Он запатентован IBM, и для использования нужно заключать с ними соглашение. Иначе суд, тюрьма...

Цитата:
Сообщение от Kronos913 Посмотреть сообщение
Есть ли какие-то еще простые алгоритмы? Так чтобы дешифратор занимал не более 1 экрана кода, может 2 максимум?
Таких нет, наверное. Просто брать что-то классическое на Паскале — даже на нашем форуме находится:
Цитата:
Сообщение от evg_m Посмотреть сообщение
Хаффман на pascal c описанием алгоритма.
Если постараться, можно выковырять оттуда упаковщик и распаковщик. Вопрос только, как хранить словарь? На коротких строках присобачивание словаря к каждой сведет на нет выигрыш от сжатия, а если общий для всех словарь хранить отдельно — вопрос уже в организации формата данных (см. выше про Git).

Цитата:
Сообщение от Kronos913 Посмотреть сообщение
И сразу вопрос, есть ли какой-то более адекватный способ посимвольного заполнения строки, чем
s:=s+c где s - string а c - добавляемый char
Выделить сразу длинный буфер через SetLength, а потом вписывать по символу через индекс или по скользящему адресу? В некоторых языках есть класс типа StringBuilder, предназначенный как раз для этого. В своей библиотеке для Delphi я делал нечто похожее, но ее код сильно завязан на другие классы, просто так его не вытащишь и тут не выложишь.
Vapaamies вне форума Ответить с цитированием
Старый 19.05.2024, 17:28   #3
NetSpace
Участник клуба
 
Аватар для NetSpace
 
Регистрация: 03.06.2009
Сообщений: 1,825
По умолчанию

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

Последний раз редактировалось NetSpace; 19.05.2024 в 17:31.
NetSpace вне форума Ответить с цитированием
Старый 20.05.2024, 10:39   #4
Vapaamies
Ваш К. О.
Участник клуба
 
Аватар для Vapaamies
 
Регистрация: 26.12.2012
Сообщений: 1,799
По умолчанию

Цитата:
Сообщение от NetSpace Посмотреть сообщение
я бы для начала просто пранализировал большинство текстов (художественные или научные), нашёл бы в них наиболее часто встречающиеся последовательности букв (2-3 буквы), и уж потом думал бы, чем их заменить....
Ну, это отдельная задача — создать единый словарь сжатия на все случаи жизни, который потом не хранить с данными, а держать внутри распаковщика. Так трудоемкость всей задачи естественным образом устремляется в потолок, грозя его пробить.
Vapaamies вне форума Ответить с цитированием
Старый 20.05.2024, 11:11   #5
Arigato
Высокая репутация
СуперМодератор
 
Аватар для Arigato
 
Регистрация: 27.07.2008
Сообщений: 15,578
По умолчанию

Цитата:
Сообщение от Vapaamies Посмотреть сообщение
создать единый словарь сжатия на все случаи жизни
Ну если затачивать алгоритм именно для текста, причем на конкретном языке, то можно выделить часто встречаемые сочетания букв. Например, беглый взгляд на ваш комментарий позволил выявить сочетание "ото", которое встречается 3 раза, "ст" - 4 раза. Проанализировав достаточно большой объем текста, можно получить пригодный к использованию в большинстве случаев словарь.

Правда кодов до 31 маловато будет для более-менее заметного результата. Тут надо смотреть в сторону оптимального кодирования и менять кодировку целиком в соответствии с частотами.

Последний раз редактировалось Arigato; 20.05.2024 в 11:13.
Arigato вне форума Ответить с цитированием
Старый 20.05.2024, 12:38   #6
Kronos913
Форумчанин
 
Регистрация: 10.02.2021
Сообщений: 640
По умолчанию

Пока что я сделал такую процедуру для дешифровки
Ну и отдельным вспомогательным кодом проанализировал, какие 30 пар символов встречаются чаще всего в тексте (13й зарезервирован под #13#10)

Код:
type
  ppChar=^PChar;
  char061= array [0..61] of char;
  p_char061= ^char061;
Код:
Procedure AddText31(var s:string; p:ppchar; codes31:p_char061);
var
  i, j, k, x:integer;
  b:byte;
begin
  j:=Length(p^);
  x:=Length(s);

  {Определяем новую длину строки}
  k:=j;
  For i:=0 to j-1 do begin
    if (p^[i]<#32) and (p^[i]>#0) then inc(k);
  end;
  SetLength(s, x+k);

  {Начинаем распаковку}
  k:=x+1;
  For i:=0 to j-1 do begin
    if (p^[i]<#32) and (p^[i]>#0) then begin
      b:=byte(p^[i])+byte(p^[i])-2;
      s[k]:=codes31[b];
      inc(k);
      s[k]:=codes31[b+1]
    end else begin
      s[k]:=p^[i];
    end;
    inc(k);
  end;
end;
Kronos913 вне форума Ответить с цитированием
Старый 20.05.2024, 13:21   #7
Vapaamies
Ваш К. О.
Участник клуба
 
Аватар для Vapaamies
 
Регистрация: 26.12.2012
Сообщений: 1,799
По умолчанию

Ёлы-палы, а мы тут развели! Как всё просто, оказывается!

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

Что однозначно могу сказать: не BOCU, в тюрьму не посодють.
Vapaamies вне форума Ответить с цитированием
Старый 20.05.2024, 13:48   #8
Arigato
Высокая репутация
СуперМодератор
 
Аватар для Arigato
 
Регистрация: 27.07.2008
Сообщений: 15,578
По умолчанию

Цитата:
Сообщение от Kronos913 Посмотреть сообщение
ppChar=^PChar;
В чем тут тайный смысл?
Arigato вне форума Ответить с цитированием
Старый 20.05.2024, 13:59   #9
Kronos913
Форумчанин
 
Регистрация: 10.02.2021
Сообщений: 640
По умолчанию

Цитата:
Сообщение от Arigato Посмотреть сообщение
В чем тут тайный смысл?
Чтобы передать по ссылке, без дублирования
Цитата:
Сообщение от Vapaamies Посмотреть сообщение
Ёлы-палы, а мы тут развели! Как всё просто, оказывается!

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

Что однозначно могу сказать: не BOCU, в тюрьму не посодють.
Я имел в виду что может есть что-то лучше?

Потому что вообще желательно как-то сделать так, чтобы итоговое сжатие не вышло меньше места, которое будет потрачено на архиватор=))
Kronos913 вне форума Ответить с цитированием
Старый 20.05.2024, 14:11   #10
Kronos913
Форумчанин
 
Регистрация: 10.02.2021
Сообщений: 640
По умолчанию

Я еще так заметил, что символы 126-167 практически не встречаются в текстах
Во всяком случае в том что у меня - так точно

И я вот думаю над тем чтобы кодировать целые слова
Kronos913 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Создать матрицу А[20, 2], заполнив первый столбец случайными числами из диапазона от 99 до 999, а во второй столбец записать 1, если число простое, 0 - если не простое tara-ta-ta Паскаль, Turbo Pascal, PascalABC.NET 2 11.11.2019 20:05
k-е простое daniil123 Паскаль, Turbo Pascal, PascalABC.NET 0 14.12.2011 23:52
Сжатие текста (по типу доков) IvaniuS Помощь студентам 2 13.04.2010 22:41
Простое или нет Superlotles Общие вопросы C/C++ 7 13.03.2010 20:30