Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.90/29: Рейтинг темы: голосов - 29, средняя оценка - 4.90
0 / 0 / 1
Регистрация: 22.10.2015
Сообщений: 55

Метод RLE, сжатие и распаковка текстовых файлов

10.03.2018, 13:09. Показов 6110. Ответов 12
Метки rle (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте, подскажите пожалуйста, у меня такое вот задание по курсовой и я не совсем понимаю его. Самое задание -
Тема: Разработка программы для сжатия и распаковки текстовых файлов методом RLE.
Описание: Идея метода состоит в том, что последовательность одинаковых байт заменяются на пары "счетчик, значение". Для большей эффективности можно ограничиться рассмотрением одной половины таблицы ASCII - кодов (от 0 до 127). Тогда старший бит в байте равный 1 будет признаком счетчика и следующий за ним байт будет восприниматься как повторяемый символ. В противном случае очередной байт воспринимается как одиночный символ. Программа должна запускаться с командной строки с тремя параметрами: режим работы (сжатие распаковка); имя входного (текстового, двоичного) файла; имя выходного (двоичного или текстового) файла

Я когда начал делать, написал такую вот функцию: в векторе fileArrIn находятся элементы считанный из файла. И когда в выходной файл (out.txt) записываются сжатые символы, количество повторений одного символа, это соответствующий символ из таблицы ASCII. А если повторений больше либо равно 127 то символ 0-ой подставляю.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void compression_file(vector<char>* fileArrIn) {
    ofstream fileOut("out.txt");
    int repet = 1;
    char code = 0;
    for (int i = 0; i < fileArrIn->size()-1; ++i) {
        if (fileArrIn->at(i) == fileArrIn->at(i + 1)) {
            code = ++repet;
            if (repet >= 127) code = 0;
        }
        else {
            if(repet > 1) fileOut << code << fileArrIn->at(i);
            else fileOut << fileArrIn->at(i);
            repet = 1;
        }
    }
    cout << "Сжатие данного файла было выполнено\n";
    fileOut.close();
}
И тут мне казалось что всё хорошо. Но потом я подумал, ведь признак счетчика у меня байт тогда. А в задание написано "Тогда старший бит в байте равный 1 будет признаком счетчика и следующий за ним байт будет восприниматься как повторяемый символ." Вот тут не совсем я понимаю, то есть один бит в байте должен быть счетчиком что ли ? И не понятно насчёт таблицы ASCII-кодов, нужно ли подставлять символы как я вот выше сделал, либо просто кол-во повторений нужно записывать, но а в чем её суть тогда вообще?
Заранее благодарю за ответ.
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
10.03.2018, 13:09
Ответы с готовыми решениями:

Разработайте приложение rle.exe, выполняющее RLE-компрессию бинарных файлов
Разработайте приложение rle.exe, выполняющее RLE-компрессию бинарных файлов с сильно разреженным содержимым, а также декомпрессию...

Узнать, выгодно ли применять RLE-сжатие для заданной строки
Макс изучает Run-Length Encoding — простой алгоритм сжатия для строк, в которых встречаются много подряд идущих одинаковых символов. ...

Написать программу на основе алгоритма RLE (сжатие/восстановление массива)
Массив из 0 и 1 целых чисел. Массив надо сжать, а затем восстановить массива. Надо написать программу по алгоритму RLE. Спасибо заранее ...

12
Эксперт .NET
 Аватар для Rius
13028 / 7595 / 1662
Регистрация: 25.05.2015
Сообщений: 23,124
Записей в блоге: 14
10.03.2018, 13:14
В байте значения от 0 до 255 включительно.
По заданию от 0 до 127 отведены под символы, или от 0x00 до 0x7f, 7 бит.
Если установлен старший бит, 0x80, то младшие 7 бит надо рассматривать как счётчик.
0x00 = 00000000b = 0
0x7f = 01111111b = 127
0x80 = 10000000b = 128
0xff = 11111111b = 255
0
0 / 0 / 1
Регистрация: 22.10.2015
Сообщений: 55
10.03.2018, 14:49  [ТС]
А ведь если старший бит установлен, то число же другое получается, ну допустим вот 2 = 0000 0010 а когда установили старший бит то уже 82 = 1000 0010
0
Эксперт .NET
 Аватар для Rius
13028 / 7595 / 1662
Регистрация: 25.05.2015
Сообщений: 23,124
Записей в блоге: 14
10.03.2018, 14:57
Ну и что? Бит можно как поставить, так и снять.
1
0 / 0 / 1
Регистрация: 22.10.2015
Сообщений: 55
10.03.2018, 15:15  [ТС]
Или же это нормально, просто при разжатии тогда можно сбрасывать эту 1 в старшем разряде, узнавать кол-во повторений символа, и тем самым отличать от одиночных символов, сжатые

Добавлено через 7 минут
Понятно, спасибо. Ну то есть если я правильно понимаю что можно сделать так:
К примеру есть последовательность "AA",
Затем после сжатия результат 82A,
Затем после разжатия снова "AA",
0
Эксперт .NET
 Аватар для Rius
13028 / 7595 / 1662
Регистрация: 25.05.2015
Сообщений: 23,124
Записей в блоге: 14
10.03.2018, 16:03
Нет.
Есть 0x01 0x01 0x01 0x01 0x01 0x02 0x03
будет 0x85 0x01 0x02 0x03
0
0 / 0 / 1
Регистрация: 22.10.2015
Сообщений: 55
10.03.2018, 16:15  [ТС]
Ой хотя нет, совсем запутался. Если 1 в старшем разряде, то тут же ещё отрицательное число в десятичной системе.

Добавлено через 3 минуты
Ну это в шестнадцатеричной

Добавлено через 6 минут
А как тогда выводить в шестнадцатеричном представлении или символы ASCII таблицы ? Просто сейчас у меня вот так вот
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
void compression_file(vector<char>* fileArrIn) {
    ofstream fileOut("out.txt");
    int repet = 1;
    signed char code = 0; //Вывод символа
    for (int i = 0; i < fileArrIn->size()-1; ++i) {
        if (fileArrIn->at(i) == fileArrIn->at(i + 1)) {
            ++repet;
        }
        else {
            code = repet; //Кол-во повторений
            code |= (1 << 7); //Установка 1 в старший бит
            if(repet > 1) fileOut << code << fileArrIn->at(i); //Вывод
            else fileOut << fileArrIn->at(i);
            repet = 1;
        }
    }
    cout << "Сжатие данного файла было выполнено\n";
    fileOut.close();
}
0
Эксперт .NET
 Аватар для Rius
13028 / 7595 / 1662
Регистрация: 25.05.2015
Сообщений: 23,124
Записей в блоге: 14
10.03.2018, 16:16
В 16-ричном.
0
0 / 0 / 1
Регистрация: 22.10.2015
Сообщений: 55
10.03.2018, 17:03  [ТС]
Понял, спасибо

Добавлено через 45 минут
Извините, всё равно не понятно немного.
Вот моя функция:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
void compression_file(vector<char>* fileArrIn) {
    ofstream fileOut("out.txt");
    int repet = 1;
    unsigned short code = 0; //Вывод символа
    for (int i = 0; i < fileArrIn->size()-1; ++i) {
        if (fileArrIn->at(i) == fileArrIn->at(i + 1)) {
            ++repet;
        }
        else {
            code = repet; //Кол-во повторений
            code |= (1 << 7); //Установка 1 в старший бит
            if(repet > 1) fileOut << hex << code << fileArrIn->at(i); //Вывод
            else fileOut << fileArrIn->at(i);
            repet = 1;
        }
    }
    cout << "Сжатие данного файла было выполнено\n";
    fileOut.close();
}
В исходном файле такая вот последовательность WWWWWWWWWWW 11 повторений
После сжатия такая 8bW
А как потом определить что 8b это число в шестнадцатеричной, а не просто 8 и b а затем одиночный символ W.
0
Эксперт .NET
 Аватар для Rius
13028 / 7595 / 1662
Регистрация: 25.05.2015
Сообщений: 23,124
Записей в блоге: 14
10.03.2018, 17:14
Цитата Сообщение от Сергей28 Посмотреть сообщение
В исходном файле такая вот последовательность WWWWWWWWWWW 11 повторений
Не WWWWWWWWWWW, а 0x57 0x57 0x57 0x57 0x57 0x57 0x57 0x57 0x57 0x57 0x57.
После будет 0x8b 0x57.
Цитата Сообщение от Сергей28 Посмотреть сообщение
А как потом определить что 8b это число в шестнадцатеричной, а не просто 8 и b а затем одиночный символ W.
Не путайте разные системы в одном месте. Принимайте только байты и проблем не будет.

Добавлено через 3 минуты
В результат пишутся байты 0x8b 0x57, а не символы 8bW или 8b57.

Добавлено через 3 минуты
На экран байты выводятся в 16-ричном представлении. В файл - просто байты, как есть.
0
0 / 0 / 1
Регистрация: 22.10.2015
Сообщений: 55
10.03.2018, 17:25  [ТС]
А мне нужен бинарный файл? Сейчас то я с текстовым файлом работаю
0
Эксперт .NET
 Аватар для Rius
13028 / 7595 / 1662
Регистрация: 25.05.2015
Сообщений: 23,124
Записей в блоге: 14
10.03.2018, 17:38
Текстовый это тот же бинарный, подходящий под некоторые условные ограничения.
Если записать бинарным, будет сжатие типа "‹W", где '' - это символ с кодом 0x8b в кодировке windows-1251.
Если как-то заморачиваться представлением всего этого в текстовом виде, как 8b W, то всплывут эти проблемы:
Цитата Сообщение от Сергей28 Посмотреть сообщение
После сжатия такая 8bW
А как потом определить что 8b это число в шестнадцатеричной, а не просто 8 и b а затем одиночный символ W.
1
0 / 0 / 1
Регистрация: 22.10.2015
Сообщений: 55
10.03.2018, 17:46  [ТС]
Понятно, спасибо Вам большое
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
10.03.2018, 17:46
Помогаю со студенческими работами здесь

Метод RLE
Написать программу сжатия полутонового bmp* файла по методу RLE

распаковка файлов
Всем привет )) Есть спецификация упакованного файла (во вложении). Каким типам данных можно сопоставить данные указанные в спецификации,...

Распаковка PAK Файлов
Есть одна игра, новая Dance - MMO, я все ресурсы игры - модели,картинки тексты и т.д находятся в этом файле. Я пытался открыть этот...

Сжатие текстовых файлов за алгоритмом GZIP
Здравствуйте! У меня возникла следующая проблема - сжать текстовый файл (с расширением txt) за алгоритмом GZIP. Вот нашел материал по...

Сжатие RLE в JScript
Доброго времени суток! Мне нужно написать скрипт. В текстовом файле input.txt записана строка (там могут быть любые символы). Необходимо...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru