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

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

09.12.2017, 17:32. Показов 2744. Ответов 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
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
09.12.2017, 17:32
Ответы с готовыми решениями:

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

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

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

32
7804 / 6568 / 2988
Регистрация: 14.04.2014
Сообщений: 28,705
16.12.2017, 07:25
Студворк — интернет-сервис помощи студентам
Актуальный вариант покажи.
0
0 / 0 / 1
Регистрация: 14.02.2017
Сообщений: 102
16.12.2017, 17:00  [ТС]
nmcf, ок.
Вот:
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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <vector> //Динамический массив (коды выписываются в вектор)
#include <map> //Ассоциативный массив 
//В map указывается на первый параметр-first и на второй параметр second;
#include <list> //Список  
//в List кладём не узлы, а указатели на них.
 
using namespace std;
 
class Node
{
    public:
     int a;
     char c;
     Node *left, *right;
     
     Node(){left=right=NULL;}
 
     Node(Node *L, Node *R) 
     {  left =  L;
        right = R;
        a = L->a + R->a;  } //конструктор принимающий 2 ссылки на правого и левого сына;
};
 
 
struct MyCompare
{
    bool operator()(const Node* l, const Node* r) const //operator()-перегружает 2 параметра в скобках
    { return l->a < r->a; }
};
 
//2 глобальные переменные
vector<bool> code;                
map<char,vector<bool> > table;  //ассоциация символа с кодом  
 
void BuildTable(Node *root)//рекурсия
{   
    if (root->left!=NULL) 
                      { code.push_back(0);
                      BuildTable(root->left);}
     
    if (root->right!=NULL)
                       { code.push_back(1);
                       BuildTable(root->right);}
   
    if (root->left==NULL && root->right==NULL) table[root->c]=code;     
    
    code.pop_back(); //Возвращаясь удаляем 0 или 1; Например:"t"=010, переносим ассоциацию символа с кодом в map и удаляем 0
    // в итоге vector будет пуст; 
}
 
 
int main (int argc, char *argv[])
{
// считаем частоты символов   
    ifstream f("Text.txt", ios::out);   
    map<char,int> m;    
    char c; 
    while (f.get(c)) m[c]++;
   if(m[c]!=0)
{
    cout<<"Text.txt is readed!";
  
// записываем начальные узлы в список list
                 
   list<Node*> t;
 
   for( map<char,int>::iterator itr=m.begin(); itr!=m.end(); ++itr) // iterator - это способ пройтись по элементам контейнера.
   {  
      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(); //pop - delete (back-конец ; front-начало)
     
     Node *parent = new Node(SonL,SonR); //create parent (ChildLeft+ChildRight)
     t.push_back(parent); //push-insert -- перемещаем 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); // * - потому что itr это указатель
   T<<endl;
   s++;
 } 
 if (s!=0) cout<<"\nCode-table is created!";
 else cout<<"\nCode-table not created, because Text.txt is empty!";
 T.close();
 
////// Выводим коды в файл Code.bin
 
    f.clear(); 
    f.seekg(0); // перемещаем указатель снова в начало файла
    
    ofstream g("Code.bin", ios::out | ios::binary);
        
    int count=0; // Счётчик 
    s=0;
    char buf=0; //Вспомогательная переменная
    while (f.get(c))//Каждый код разбиваем на 8 и преобразовать в байт
    { vector<bool> x = table[c];
      for(int n=0; n<x.size(); n++)
       {buf = buf | x[n]<<(7-count); //бежим от 0 до 8  
        count++; s++;  
        if (count==8) { count=0; g<<buf; buf=0; } // обнуляем count, так как байт у нас 8;
       }
    }
    if (s!=0)cout<<"\nText file is archived!";
    else cout<<"\nText file not archived, because it is empty!";
    f.close();
    g.close();   
    
// считывание из файла Code.bin и преобразование обратно
 
    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) ) ; //бежим от 0 до 8
        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();} // обнуляем count, так как байт у нас 8;
    }
    if (s!=0) cout<<"\nBinary file is coded!";
    else cout<<"\nBinary file not coded, because text file is empty!";
    F.close();
    D.close();
}
else cout<<"Text.txt is empty!";    
    system("Pause>>nul");
    return 0;
}
0
7804 / 6568 / 2988
Регистрация: 14.04.2014
Сообщений: 28,705
16.12.2017, 19:31
m.size() в 62-й строке надо проверять.
После цикла в 126 у тебя может быть не дозаписан последний блок, если последний байт не заполнился до конца (count > 0).
0
0 / 0 / 1
Регистрация: 14.02.2017
Сообщений: 102
16.12.2017, 19:46  [ТС]
nmcf, В смысле надо добавить (count>0)? А в какую строку?
0
7804 / 6568 / 2988
Регистрация: 14.04.2014
Сообщений: 28,705
16.12.2017, 20:19
После цикла проверяй и делай запись buf.
1
0 / 0 / 1
Регистрация: 14.02.2017
Сообщений: 102
16.12.2017, 20:38  [ТС]
nmcf, я наверно туплю, потому что я не понимаю в какой номер строки вставить if (count>0). Я только смотрю на 131 строку, потому что там идёт запись buf.
0
7804 / 6568 / 2988
Регистрация: 14.04.2014
Сообщений: 28,705
16.12.2017, 21:17
134.
0
0 / 0 / 1
Регистрация: 14.02.2017
Сообщений: 102
16.12.2017, 22:13  [ТС]
nmcf, я добавил в 134 строчку:
C++
1
if (count>0) g<<buf;
Теперь до конца всё добавляет, но добавляются ещё к этому почему то 2 буквы о;
0
7804 / 6568 / 2988
Регистрация: 14.04.2014
Сообщений: 28,705
16.12.2017, 23:08
Потому что остаток байта нулями заполнен. Надо как-то сохранять это в файл. Самое простое - записать размер исходного файла.
0
0 / 0 / 1
Регистрация: 14.02.2017
Сообщений: 102
16.12.2017, 23:22  [ТС]
nmcf, И как это правильно сделать и написать?
0
7804 / 6568 / 2988
Регистрация: 14.04.2014
Сообщений: 28,705
16.12.2017, 23:39
Определить размер и записать целое в в начало файла, например. И так же извлечь при декодировании.
0
0 / 0 / 1
Регистрация: 14.02.2017
Сообщений: 102
17.12.2017, 15:17  [ТС]
nmcf, типо
C++
1
 int size; size=f.tellg();
и что потом с этим делать или я что то не то понял?
0
7804 / 6568 / 2988
Регистрация: 14.04.2014
Сообщений: 28,705
17.12.2017, 21:29
В цикл подсчёта частот счётчик добавь. Это и будет размер. После запишешь его в файл через write().
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
17.12.2017, 21:29

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

Убрать лишний элемент
Есть товар в каталоге - http://elamed.com/catalog/catalog/magnitoterapiya-magnitoterapiya-v-domashnikh-usloviyakh/tovar-6 Нужно убрать из...

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

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

Как удалить лишний спарсенный элемент?
Всем привет ! Я парсю дату с этого ресурса.Все бы хорошо,но есть одно но.Когда я получил эти данные (22 Августа 2019 10:45 187) парсится...


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

Или воспользуйтесь поиском по форуму:
33
Ответ Создать тему
Новые блоги и статьи
Особенности gif сгенерированных в Си
russiannick 21.10.2026
Рассмотрим генерацию gif файлов, которые в Си имеют свои особенности. Gif представляет собой графический формат популярный в интернете. Посмотрим на палитру. Gif файл сгенерированный в си отличается. . .
FPS контроллер с анимированными Y-Bot и 3D-звуком miniaudio (Box3D, Recast, BehaviorTree.CPP, ozz-animation, ImGui, OpenGL и SDL3)
8Observer8 18.10.2026
Содержание блога | English Version Полное мультиплатформенное руководство по стартовому проекту с FPS-контроллером игрока, анимированными роботами Y-Bot с 4-слойным блендингом, 3D-физикой Box3D,. . .
Локальный http сервер
Argus19 17.10.2026
Локальный http сервер На работе, на двух локальных компьютерах круглосуточно работают программы опроса приборов с записью в книги Excel,которые раз в сутки записываются на сервер компании. Т. к. . . .
Копировать Windows на новый диск на UEFI
damix 17.10.2026
https:/ / uriesk. wordpress. com/ 2016/ 11/ 01/ move-window-10-to-ssd-on-a-uefi-dualboot-system-with-basic-linux-tools/ TL DR Вставляем диск, а старый подключаем через переходник, грузимся с лайва. . .
ИИ не может найти нужный язык в списке
Supersumestria 05.10.2026
Я ему даю вот такое изображение и прошу найти и подчеркнуть немецкий язык. Возвращает он вот это: https:/ / i. **********/ vqBWLe2. png Нужную строчку в 3й колонке просто выдумал. . Это. . .
Новая последняя моя музыка в SUNO
zorxor 05.10.2026
Здравствуйте, дорогие мои друзья! С большой радостью я хотел бы представить вам свою новую последнею музыку, которую сгенерировала мне по моей просьбе нейросеть SUNO. С уважением, zorxor. Это. . .
Программный домашний кинотеатр
russiannick 27.09.2026
Сподобился на программный домашний кинотеатр. В качестве ЯВУ по традиции выбрал js. В помощники взял Яндекс-Алису. Было создано три зала на разные интересы. исторические и ретро сериал Хичкок. . .
Беседа с ИИ о программистах, недопускающих к созданию и правке кода генеративные ИИ и причины этого
zorxor 21.09.2026
Раньше я радовался или получал некоторые эмоции, пусть небольшие, но всё же, от самого процесса написания кода, рекомпиляции и запуска, видя постепенное развитие программы и прочее. А теперь лень. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru