Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.63/8: Рейтинг темы: голосов - 8, средняя оценка - 4.63
0 / 0 / 1
Регистрация: 14.02.2017
Сообщений: 102
1

Хаффман. Выводит лишний элемент

09.12.2017, 17:32. Показов 1493. Ответов 32
Метки нет (Все метки)

Здравствуйте. Делаю алгоритм Хаффмана через файлы. Но есть одна проблема, которую я понять не могу. Когда считываю пустой файл, то в таблице бинарных кодов для элементов, вместо пустоты как и в других файлах(кодированный файл, раскодированный файл), появляется буква "я". Если в файле написать текст, то в таблице все буквы + эта буква "я" при чем все буквы и знаки препинания с бинарными кодами, а буква "я" без кода -> (я : ). - В принципе понятно почему она без кода, но не могу понять откуда она берётся. В раскодированном файле тот же самый текст, но после точки стоит эта буква "я". И есть случай, если не поставить знак препинания в тексте, то в раскодированном файле будет весь тот же самый текст, но без последней буквы и буквы "я" там нет, но в таблице она всё ровно есть. Помогите пожалуйста разобраться с этой проблемой. Вроде говорят, что проблема в eof() и надо вроде поставить size(), куда не понимаю.
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
48
49
50
51
52
53
int main (int argc, char *argv[])
{
// считаем частоты символов   
    ifstream f("Text.txt", ios::out);   
    map<char,int> m;    
    while (!f.eof())
    { char c;
          c = f.get(); 
      m[c]++;}
 
   list<Node*> t;
   for( map<char,int>::iterator itr=m.begin(); itr!=m.end(); ++itr) 
   {  
      Node *p = new Node;
      p->c = itr->first; //Загружаем узлы
      p->a = itr->second; //Загружаем узлы  
      t.push_back(p);  //указатель скидываем в List
    }   
    
 
//  создаем дерево     
 
  while (t.size()!=1) //пока в списке не останиться один элемент (На каждом шаге убираем 2, а добавляем 1)
  {  
     t.sort(MyCompare());// Сортировка указателей.
    
     Node *SonL = t.front();
     t.pop_front(); // удаляем child
     Node *SonR = t.front(); 
     t.pop_front();
     
     Node *parent = new Node(SonL,SonR); 
     t.push_back(parent); 
 
  }
    
    Node *root = t.front();   //root - указатель на вершину дерева
 
// создаем пары 'символ-код':           
 
 BuildTable(root);   
 
map<char, vector<bool> >::iterator it;
 vector<bool>::iterator itr;
 ofstream T("Table.txt", ios::out);
 int s=0;
 for (it = table.begin(); it != table.end(); it++)
 {
  T << it->first << " : ";
  for (itr = table[it->first].begin(); itr != table[it->first].end(); itr++)
   T << (*itr); 
   T<<endl;
 }
0

Помощь в написании контрольных, курсовых и дипломных работ здесь.

Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
09.12.2017, 17:32
Ответы с готовыми решениями:

Список, выводит лишний нолик
Задание таково: Внести значения, выбрать количество элементов которые должны вывестись на экран с...

Лишний раз выводит сообщение
Добрый вечер. Уже час бьюсь над следующей проблемой. Почему выводится сообщение: &quot;Oshibka!...

Контейнер map. Выводит лишний символ
Вот код. Шифр простой замены. В конце выводит последний символ 2 раза подряд. #include &lt;iostream&gt;...

Скрипт выводит лишний элемент массива
Доброго времени суток, подскажите где я не прав и в какую сторону смотреть. PHP скрипт прогоняет...

32
6992 / 6030 / 2738
Регистрация: 14.04.2014
Сообщений: 25,792
09.12.2017, 17:45 2
До конца дочитай тему, из которой это взял. Объясняли сто раз, что eof() не работает так, как вас там учат.
C++
1
2
    char c;
    while (f.get(c)) m[c]++;
1
0 / 0 / 1
Регистрация: 14.02.2017
Сообщений: 102
09.12.2017, 18:01  [ТС] 3
nmcf, Всё сработало, но когда файл пуст, то программа вылетает.
0
6992 / 6030 / 2738
Регистрация: 14.04.2014
Сообщений: 25,792
09.12.2017, 18:25 4
Просто учитывай это как особый случай.
0
3418 / 2777 / 752
Регистрация: 25.03.2012
Сообщений: 10,099
Записей в блоге: 1
09.12.2017, 18:40 5
так это не ты придумал алгоритм?
а почему не полностью выложен код? От кого прячешь?
0
0 / 0 / 1
Регистрация: 14.02.2017
Сообщений: 102
09.12.2017, 18:53  [ТС] 6
Kuzia domovenok, Да это не мой алгоритм, так как я только 2 год учу с++ и придумать свой алгоритм по хаффману не могу. Но мне он более понятен из всех найденных примеров в нете так как всё объяснили в этом коде. Я конечно же не множко его поменял под себя в частности, всё через файлы делаю и ещё буду из main убирать и через функции делать. Весь не выкладывал, потому что ошибка в коде была только в чтение файла.
0
nmcf
09.12.2017, 18:57
  #7

Не по теме:

Kuzia domovenok, это написал кто-то сто лет назад, а они все копируют. Я уже не первый раз вижу.

0
3418 / 2777 / 752
Регистрация: 25.03.2012
Сообщений: 10,099
Записей в блоге: 1
09.12.2017, 18:58 8
ну, я, например, не смог в него вникнуть, т.к. не понял, где создаётся table который упомянут в it = table.begin()
и как он потом читается тоже не ясно
0
nmcf
09.12.2017, 19:00
  #9

Не по теме:

Он не всё показал, наверное.

0
0 / 0 / 1
Регистрация: 14.02.2017
Сообщений: 102
09.12.2017, 23:16  [ТС] 10
nmcf, А исправлять eof() только в том одном месте надо было? Потому что если пишешь в файле "Radeon", то раскодируется также "Radeon", а если пишешь "Radeon." , то раскодируется "Radeo". Пропала точка и последняя буква.
Потому что есть ещё:
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
//Выводим коды в файл Code.bin
ofstream g("Code.bin", ios::out | ios::binary);
        
    int count=0; 
    s=0;
    char buf=0; 
    while (!f.eof())
    { char c=f.get();
        vector<bool> x = table[c];
      for(int n=0; n<x.size(); n++)
       {buf = buf | x[n]<<(7-count);  
        count++; s++;  
        if (count==8) { count=0; g<<buf; buf=0; } 
       }
    }
 
// Раскадировка
ifstream F("Code.bin", ios::in | ios::binary);
ofstream D("Decode.txt", ios::out | ios::binary);
    
    Node *p = root; 
    count=0; 
    s=0;
    char byte; 
    byte = F.get();
    while (!F.eof())
    {   bool b = byte & (1 << (7-count) ) ; 
        if (b) p=p->right; else p=p->left;
        if (p->left==NULL && p->right==NULL) {D<<p->c; p=root;}  
        count++; s++;
        if (count==8) {count=0; byte = F.get();} 
    }
0
6992 / 6030 / 2738
Регистрация: 14.04.2014
Сообщений: 25,792
09.12.2017, 23:18 11
А у тебя ещё где-то есть eof()?
0
0 / 0 / 1
Регистрация: 14.02.2017
Сообщений: 102
10.12.2017, 19:02  [ТС] 12
nmcf, нету.

Добавлено через 18 часов 37 минут
nmcf, Так в других двух тоже надо исправлять eof()? В третьем(раскадировка) не знаю как исправить eof()?
0
6992 / 6030 / 2738
Регистрация: 14.04.2014
Сообщений: 25,792
11.12.2017, 10:43 13
Ты же сказал, что больше нет eof().
0
0 / 0 / 1
Регистрация: 14.02.2017
Сообщений: 102
11.12.2017, 17:02  [ТС] 14
nmcf, я имел в виду, что только в этих 3 местах есть eof() и больше нету. Поэтому и выложил ещё 2 места где есть eof() :кодировка и раскодировка.
0
6992 / 6030 / 2738
Регистрация: 14.04.2014
Сообщений: 25,792
11.12.2017, 18:02 15
Везде.
0
0 / 0 / 1
Регистрация: 14.02.2017
Сообщений: 102
11.12.2017, 18:15  [ТС] 16
nmcf, а как здесь поменять eof()?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
ifstream F("Code.bin", ios::in | ios::binary);
ofstream D("Decode.txt", ios::out | ios::binary);
    
    Node *p = root; 
    count=0; 
    s=0;
    char byte; 
    byte = F.get();
    while (!F.eof())
    {   bool b = byte & (1 << (7-count) ) ; 
        if (b) p=p->right; else p=p->left;
        if (p->left==NULL && p->right==NULL) {D<<p->c; p=root;}  
        count++; s++;
        if (count==8) {count=0; byte = F.get();} 
    }
Добавлено через 7 минут
nmcf, F.get() от чего?
0
6992 / 6030 / 2738
Регистрация: 14.04.2014
Сообщений: 25,792
11.12.2017, 18:22 17
Здесь можешь оставить как есть.
0
0 / 0 / 1
Регистрация: 14.02.2017
Сообщений: 102
11.12.2017, 18:31  [ТС] 18
nmcf, Оставил так, но всё ровно вместо "Radeon." выдаёт "Radeo" .

Добавлено через 4 минуты
Забывает раскодировать 1 или 2 элемента. В таблицу всё правильно заносит.
0
6992 / 6030 / 2738
Регистрация: 14.04.2014
Сообщений: 25,792
11.12.2017, 23:47 19
Ты откуда это взял? Были темы с правильной реализацией.
0
0 / 0 / 1
Регистрация: 14.02.2017
Сообщений: 102
15.12.2017, 18:41  [ТС] 20
nmcf, https://www.youtube.com/watch?v=KNVPFVG49Oc отсюда я брал, там только один комментарий по этому поводу есть для исправления: Это происходит потому что когда последняя буква кодируется всеми нулями, то это воспринимается как конец файла функцией eof(). Чтобы всё работало корректнее, можно завести переменную size и записать туда размер исходной строки. А при считывании проверять не на конец файла, а через size, уменьшая значение с каждым прочитанным символом.
А как это сделать правильно я не знаю. Разве на cyberforum есть этот же код с правильной реализацией?
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
15.12.2017, 18:41

Убрать лишний элемент
Есть товар в каталоге -...

Лишний элемент-полоса
Здравствуйте! Прошу помощи. Убил на проблему 6 часов, решения не нашел. На странице увеличил в...

лишний элемент массива mysql_fetch_array
Сделал выбору из базы $users_data = mysql_query(&quot; SELECT * FROM `{$this-&gt;table_user}`...

Как удалить лишний спарсенный элемент?
Всем привет ! Я парсю дату с этого ресурса.Все бы хорошо,но есть одно но.Когда я получил эти данные...

Как убрать лишний элемент с портрета
Доброго здравия... Так случилось, что знакомый начинающий фотограф начал озадачиваться многими...

Лишний элемент после вызова Split
Вылазеет лишний символ в файле using System; using System.Text; using...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.