Форум программистов, компьютерный форум CyberForum.ru

Кодирование длин серий RLE - C++

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 30, средняя оценка - 4.73
EvgeZ
0 / 0 / 0
Регистрация: 11.12.2013
Сообщений: 26
20.04.2014, 23:08     Кодирование длин серий RLE #1
Есть код алгоритма кодирования длин серий RLE.
Но есть траблы с декодированием
Вот код
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <iostream>
#include <fstream>
 
using namespace std;
 
int main()
{   
    std::ifstream file("INPUT_TEXT.txt");
    std::ofstream file_compr("COMPRESSED_TEXT.txt");
    
    char sym;//символ, который мы будем считывать
    int kol=1;// количество повторяющихся символов
 
    while(!file.eof())
    {
        file.get(sym);//считываем символ
        if(sym!=file.peek())// если символ не совпадает со слеующим символом в файле
        {
            file_compr<<kol<<sym;// записываем результаты в выходной файл
            kol=0;
        }
        kol++;
    }
 
    std::ifstream f1("COMPRESSED_TEXT.txt");
    std::ofstream file_decompr("DECOMPRESSED_TEXT.txt");
 
    char sym1,sym2;// предыдущий и последующий символы
    while(f1.peek()!=EOF)
    {
        f1>>sym1>>sym2;// считываем символы
        for(int i=0;i<sym1-48;i++)
            file_decompr<<sym2;
    }
 
    system("PAUSE");
    return 0;
}
Добавлено через 18 секунд
Нужна помощь))
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
20.04.2014, 23:08     Кодирование длин серий RLE
Посмотрите здесь:

Нахождение серий символов в строке C++
RLE компресія на с++ C++
Метод RLE C++
Реализация алгоритма RLE C++
C++ алгоритм RLE
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
nmcf
4306 / 3727 / 1256
Регистрация: 14.04.2014
Сообщений: 14,599
21.04.2014, 07:08     Кодирование длин серий RLE #2
Не будет так работать. Когда записываешь количество, оно должно быть фиксированной длины, например 2 символа. Соответственно длины будут от 01 до 99. Это если всё текстом сохранять.

Добавлено через 6 минут
Скажем, "БББ" должно стать "Б03". Извлекать посимвольно get(sym); get(len1); get(len2);. Потом len1 и len2 объединять в строку, конвертировать в число повторений.
Toshkarik
 Аватар для Toshkarik
1139 / 856 / 50
Регистрация: 03.08.2011
Сообщений: 2,381
Завершенные тесты: 1
21.04.2014, 08:55     Кодирование длин серий RLE #3
Это просто пример, там изначально предполагается, что повторений не будет больше 9.
nmcf
4306 / 3727 / 1256
Регистрация: 14.04.2014
Сообщений: 14,599
21.04.2014, 11:02     Кодирование длин серий RLE #4
В любом случае экстрактор замени на get и цикл не с peek, а также как первый с eof().

Добавлено через 1 минуту
Потоки не забывай закрывать.
Kuzia domovenok
 Аватар для Kuzia domovenok
1883 / 1738 / 116
Регистрация: 25.03.2012
Сообщений: 5,907
Записей в блоге: 1
21.04.2014, 11:44     Кодирование длин серий RLE #5
Цитата Сообщение от Toshkarik Посмотреть сообщение
там изначально предполагается, что повторений не будет больше 9.
а ты откуда знаешь?
Toshkarik
 Аватар для Toshkarik
1139 / 856 / 50
Регистрация: 03.08.2011
Сообщений: 2,381
Завершенные тесты: 1
21.04.2014, 11:57     Кодирование длин серий RLE #6
Цитата Сообщение от Kuzia domovenok Посмотреть сообщение
а ты откуда знаешь?
Да все оттуда же.
Kuzia domovenok
 Аватар для Kuzia domovenok
1883 / 1738 / 116
Регистрация: 25.03.2012
Сообщений: 5,907
Записей в блоге: 1
21.04.2014, 12:41     Кодирование длин серий RLE #7
Toshkarik, в смысле? Ты сам писал этот пример что ли?
Toshkarik
 Аватар для Toshkarik
1139 / 856 / 50
Регистрация: 03.08.2011
Сообщений: 2,381
Завершенные тесты: 1
21.04.2014, 13:01     Кодирование длин серий RLE #8
Нет. Но, прочитав бегло пост по ссылке, понял с первого раза. Там все вполне понятно описано, у автора была цель показать суть, а не предоставить готовое решение, которое, кстати, не всегда тривиальное.
EvgeZ
0 / 0 / 0
Регистрация: 11.12.2013
Сообщений: 26
21.04.2014, 16:52  [ТС]     Кодирование длин серий RLE #9
nmcf, а если записывать число в типе int? Ну и сделать считывание таким образом : число->символ->декодирование. До конца файла естественно.
nmcf
4306 / 3727 / 1256
Регистрация: 14.04.2014
Сообщений: 14,599
21.04.2014, 16:57     Кодирование длин серий RLE #10
Можно и в int, но нужно точно определиться с количеством байт текстового представления этого int. Делай тогда проверку, чтобы кодировалось не больше 9 символов в последовательности.

Добавлено через 1 минуту
Ты раскодировку исправил на get()?
EvgeZ
0 / 0 / 0
Регистрация: 11.12.2013
Сообщений: 26
21.04.2014, 17:36  [ТС]     Кодирование длин серий RLE #11
nmcf, еще нет

Добавлено через 7 минут
вот
C++
1
2
3
4
5
6
7
8
9
10
    char sym1;// предыдущий и последующий символы
    int sym2;
    while(!f1.eof())
    {
        f1>>sym1>>sym2;// считываем символы
        //f1.get(sym1);
        //f1.get(sym2);
        for(int i=0;i<sym1-48;i++)
            file_decompr<<sym2;
    }
ничего не изменилось
скорее всего, я не правильно прописал считывание
nmcf
4306 / 3727 / 1256
Регистрация: 14.04.2014
Сообщений: 14,599
21.04.2014, 20:53     Кодирование длин серий RLE #12
Сообщение было отмечено автором темы, экспертом или модератором как ответ
Вот так работает, но у меня почему-то количество последнего символа удваивается. Проверь у себя.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
    ifstream file("INPUT_TEXT.txt");
    ofstream file_compr("COMPRESSED_TEXT.txt");
    
    char sym; //символ, который мы будем считывать
    int kol=1;// количество повторяющихся символов
 
    while(file.good())
    {
        file.get(sym);//считываем символ
        if(sym != file.peek() || kol == 9)// если символ не совпадает со следующим символом в файле
        {
            file_compr << kol << sym;
            // записываем результаты в выходной файл
            kol=0;
        }
        kol++;
    }
 
    file.close();
    file_compr.close();
 
    ifstream f1("COMPRESSED_TEXT.txt");
    ofstream file_decompr("DECOMPRESSED_TEXT.txt");
 
    char sym1,sym2;// предыдущий и последующий символы
    const char zero = '0';
    while(f1.good())
    {
        f1.get(sym1);
        f1.get(sym2);
        for(int i=0; i < sym1-zero; i++)
            file_decompr << sym2;
    }
 
    f1.close();
    file_decompr.close();
 
    system("PAUSE");
    return 0;
EvgeZ
0 / 0 / 0
Регистрация: 11.12.2013
Сообщений: 26
21.04.2014, 22:35  [ТС]     Кодирование длин серий RLE #13
nmcf, да, есть такое.
не пойму, зачем менять кодирование на части по 9 штук?
nmcf
4306 / 3727 / 1256
Регистрация: 14.04.2014
Сообщений: 14,599
21.04.2014, 23:11     Кодирование длин серий RLE #14
Чтобы длина обозначалась одним символом. 10 - это уже 2 символа. Можно и под такое сделать программу. Только тогда придётся лидирующие нули дописывать. Либо надо работать с закодированным файлом как с бинарным, тогда до 255 можно.

Меня вот проблема с удвоением волнует.
EvgeZ
0 / 0 / 0
Регистрация: 11.12.2013
Сообщений: 26
21.04.2014, 23:57  [ТС]     Кодирование длин серий RLE #15
nmcf, допустим, что реализовать кодирование таким образом - пусть не самый хороший способ, но его удобно использовать для декодирования. Тогда вопрос есть:
Цитата Сообщение от nmcf Посмотреть сообщение
const char zero = '0';
для чего это?
nmcf
4306 / 3727 / 1256
Регистрация: 14.04.2014
Сообщений: 14,599
22.04.2014, 08:07     Кодирование длин серий RLE #16
Чтобы преобразовать символ числа в само число. Просто для наглядности.

Добавлено через 4 минуты
Спецы, посмотрите программу, которую я выше приводил. Почему удваивается последняя последовательность?
Пример:
пусть в INPUT_TEXT.txt: "YYYYYYYYYTRR"
в COMPRESSED_TEXT.txt получается "9Y1T2R"
а вот в DECOMPRESSED_TEXT.txt получается "YYYYYYYYYTRRRR"
Т. е. количество "R" получается в 2 раза больше требуемого. Если будет "4R", то на выходе получается восемь символов - "RRRRRRRR".
Toshkarik
 Аватар для Toshkarik
1139 / 856 / 50
Регистрация: 03.08.2011
Сообщений: 2,381
Завершенные тесты: 1
22.04.2014, 08:32     Кодирование длин серий RLE #17
Потому что при чтении последней пары файл все еще в состоянии 'good', флаг eof ставится только если есть попытка чтения за конец потока. f1.get(sym1); и f1.get(sym2); не изменяют sym1 и sym2 так как при попытки чтения sym1 устанавливается уже тот самый eof. В них хранятся предыдущие значения, следовательно исполняется цикл еще раз.
nmcf
4306 / 3727 / 1256
Регистрация: 14.04.2014
Сообщений: 14,599
22.04.2014, 08:44     Кодирование длин серий RLE #18
Да, это я не учёл.
EvgeZ
0 / 0 / 0
Регистрация: 11.12.2013
Сообщений: 26
22.04.2014, 17:21  [ТС]     Кодирование длин серий RLE #19
Собственно, вы исправили программу и довели ее до рабочего состояния. Единственное, но не очень серьезное замечание в том, что кодирование происходит не на все 100 процентов, т.к. считываются символы до 9 штук
вот код уже рабочей проги:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include <iostream>
#include <fstream>
#include <string>
 
using namespace std;
 
int main()
{   
    ifstream file("INPUT_TEXT.txt");
    ofstream file_compr("COMPRESSED_TEXT.txt");
    
    char sym; //символ, который мы будем считывать
    int kol=1;// количество повторяющихся символов
 
    while(file.good())
    {
        file.get(sym);//считываем символ
        if(sym != file.peek() || kol==9) // если символ не совпадает со следующим символом в файле
        {
            file_compr << kol << sym; // записываем результаты в выходной файл
            kol=0;
        }
        kol++;
    }
 
    file.close();
    file_compr.close();
 
    ifstream f1("COMPRESSED_TEXT.txt");
    ofstream file_decompr("DECOMPRESSED_TEXT.txt");
 
    char sym1,sym2; // предыдущий и последующий символы
    const char zero = '0';
    while(f1.peek()!=EOF)
    {
        f1.get(sym1);
        f1.get(sym2);
        for(int i=0; i < sym1 - zero; i++)
            file_decompr << sym2;
    }
 
    f1.close();
    file_decompr.close();
 
    system("PAUSE");
    return 0;
}
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
22.04.2014, 17:36     Кодирование длин серий RLE
Еще ссылки по теме:

C++ ошибки для RLE
C++ Алгоритм кодирование длин серий
C++ Компрессия RLE

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

Или воспользуйтесь поиском по форуму:
nmcf
4306 / 3727 / 1256
Регистрация: 14.04.2014
Сообщений: 14,599
22.04.2014, 17:36     Кодирование длин серий RLE #20
У меня считывается сколько угодно символов. Просто кодируется группами по 9. Если, скажем, будет 18 символов "Y", то получишь "9Y9Y".
Yandex
Объявления
22.04.2014, 17:36     Кодирование длин серий RLE
Ответ Создать тему
Опции темы

Текущее время: 05:37. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru