Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.67/6: Рейтинг темы: голосов - 6, средняя оценка - 4.67
12 / 10 / 5
Регистрация: 27.08.2015
Сообщений: 236

Прошу сделать ревью кода

22.01.2016, 21:25. Показов 1285. Ответов 3
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Всем доброго времени суток.
Есть код, который очень далек от идеала и мне хотелось бы что бы гуру форума подсказали как можно его к ниму приблизить? Реализовал алгоритм Хаффмана

Кликните здесь для просмотра всего текста
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
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
#include <iostream>
#include <vector>
#include <map>
#include <list>
#include <fstream>
 
using namespace std;
 
/*
 * Class of Huffman node tree
 */
class Node{
public:
    int number; //frequency of occurrence of symbol in the file
    char symbol; //value (only for leaves)
    Node *left, *right; //pointers to the left and right sons
 
    Node(){ // constructor overload
        left = right = NULL;
    }
 
    Node (Node *L, Node *R){ //constructor takes a reference to the left and right son
        left = L;
        right = R;
        number = L->number + R->number; //the sum of two nodes values
    }
 
    ~Node(){
        delete left;
        delete right;
    }
};
 
/*
 * Struct for sorting elements in the list
 */
struct MyCompare{
    bool operator()(Node* left, Node* right){ //parameters overload
        return left->number < right->number;
    }
};
 
map <char, vector <bool> > symbolCodeTable; //table with code and symbol association (table for coding)
Node *treeRoot; //root of a binary tree
vector <bool> code; //binary vector
 
/*
 * Associate a symbol with its code starting from the root
 * and passing through the tree
 */
void symbolCodeAssociation(Node *root){
    if (root->left != NULL) {
        code.push_back(0); //put zero in the vector
        symbolCodeAssociation(root->left); //run the function for the left son
    }
    if (root->right!= NULL) {
        code.push_back(1); //put one in the vector
        symbolCodeAssociation(root->right); //run the function for the right son
    }
    if(root->left==NULL && root->right==NULL) { //if find a node with the letter
        symbolCodeTable[root->symbol]=code; //associate symbol with the code
    }
    code.pop_back(); //reducing code by one
}
 
/*
 * Build a code tree for characters of the text according to the Huffman's algorithm
 */
void buildTree(const map <char, int> &symbolFrequencyAssociation){
    list <Node*> pointer; //list of pointers to the node
 
    //go through map and load nodes
    for (map <char, int>::const_iterator iter = symbolFrequencyAssociation.begin(); iter != symbolFrequencyAssociation.end(); ++iter) {
        Node *newNode = new Node; //create a new node
        newNode->symbol = iter->first;
        newNode->number = iter->second;
        pointer.push_back(newNode); //put pointer to the list
    }
 
    while (pointer.size()!=1) { //until map contains one element
        pointer.sort(MyCompare());
 
        Node *leftSon = pointer.front(); //take the first element
        pointer.pop_front(); //delete it
        Node *rightSon = pointer.front(); //take the second element
        pointer.pop_front(); //delete it
        Node *parent = new Node(leftSon, rightSon); //send to the constructor and find parent value
        pointer.push_back(parent); //put parent to the list
 
    }
    treeRoot = pointer.front(); //pointer to the root
 
    code.clear(); //free up memory
    symbolCodeTable.clear();
    symbolCodeAssociation(treeRoot); //creating a pair of character-code
}
 
/*
 * Function prototypes
 */
void archive(); // encoding function
void dearchive(); // decoding function
 
int main (){
    int choice;
    cout << "*-*-*-*-*-*-*-*_Huffman Archiver_*-*-*-*-*-*-* \n" << endl;
    cout << "    __ __ __ __\n   /           /|\n  /archive.huf/ |\n /__ __ __ __/ /|\n|__ __ __ __|/ /|\n|__ __ __ __|/ /\n|__ __ __ __|/\n" << endl;
    cout << "1.File archiving "<<endl;
    cout << "2.Unzip the file \n" << endl;
    cout << "Please, make your choice: ";
    cin >> choice;
    switch (choice) {
    case 1:
        archive();
        cout << "\nFile was saved with name: 'archive.huf' \n" << endl;
        cout << "Press Enter key to exit" << endl;
        break;
    case 2:
        dearchive();
        cout << "\nUnzipping successful \nFile was saved with name: 'archive.huf' \n" << endl;
        cout << "Press Enter key to exit" << endl;
        break;
    default:
        cout << "\nYou made a wrong choice! \n" << endl;
        cout << "Press Enter key to exit" << endl;
        break;
    }
    return 0;
}
 
void archive(){
    ifstream inputFile("file.txt", ifstream::binary);
    map <char,int> symbolFrequencyAssociation;
    int number;
    int file_size = 0;
 
    // until not the end of file, get one byte
    while((number = inputFile.get()) != EOF) {
        symbolFrequencyAssociation[number]++;
        ++file_size;
    }
 
    buildTree(symbolFrequencyAssociation);
    // move the pointer to the beginning of the file (as it's at the moment at the end)
    inputFile.clear();
    inputFile.seekg(0);
 
    ofstream outputArchive("archive.huf", ios::binary);
    outputArchive.write(reinterpret_cast<char *>(&file_size), sizeof(file_size)); // write the file size
    char size = symbolFrequencyAssociation.size();
    outputArchive.write(reinterpret_cast<char *>(&size), sizeof(size)); // the number of symbols
    // write symbols with the frequencies
    for (map <char, int>::iterator iterator = symbolFrequencyAssociation.begin(); iterator != symbolFrequencyAssociation.end(); ++iterator){
        char first = iterator->first;
        int second = iterator->second;
        outputArchive.write(reinterpret_cast<char *>(&first), sizeof(char)); // typecast to char *
        outputArchive.write(reinterpret_cast<char *>(&second), sizeof(int));
    }
 
    int count = 0;
    char buf = 0;
 
    while (true) {
        char byte = inputFile.get(); //get one byte
        if (inputFile.eof()) {
            break;
        }
 
        vector <bool> bin = symbolCodeTable[byte];//read code of symbol
 
        for (int i = 0; i < bin.size(); i++) {
            buf = buf | bin[i]<<(7-count); //check if it's 0 or 1 and put it to byte
            count++;
            if(count == 8){ //when byte is full, than zeroize counter, put this byte to the archive and zeroize buffer
                count = 0;
                outputArchive<<buf; //wright code into file
                buf = 0;
            }
        }
    }
 
    if (count != 0) {
        outputArchive << buf; //put last, not full byte
    }
    inputFile.close();
    outputArchive.close();
    delete treeRoot; //free up memory
}
 
void dearchive(){
    ifstream inputArchive("archive.huf", ios::in | ios::binary); // archive file
    ofstream outputFile("file_dec.txt", ios::out | ios::binary);// deachive file
 
    int file_size;
 
    inputArchive.read(reinterpret_cast<char *>(&file_size), sizeof(file_size)); // read the file size
    map <char,int> symbolFrequencyAssociation;
    char size;
 
    inputArchive.read(reinterpret_cast<char *>(&size), sizeof(size)); // typecast to char *
    // read symbols with the frequencies
    for (int i = 0; i < size; ++i) {
        char first;
        int second;
        inputArchive.read(reinterpret_cast<char *>(&first), sizeof(char));
        inputArchive.read(reinterpret_cast<char *>(&second), sizeof(int));
        symbolFrequencyAssociation[first] = second;
    }
 
    buildTree(symbolFrequencyAssociation);
 
    Node *pointer = treeRoot; //pointer to the root
    int count=0;
    char byte;
    byte = inputArchive.get(); //get byte
 
    while (!inputArchive.eof()) {
        if (byte & (1 << (7-count))) { //check if it's 0 or 1
            pointer = pointer->right;
        } else {
            pointer = pointer->left;
        }
        if (pointer->left==NULL && pointer->right==NULL) {
            outputFile << pointer->symbol;
            if (--file_size == 0) {
                break; //all characters are encoded - stop decoding
            }
            pointer = treeRoot;
        }
        count++;
        if (count == 8){ //when byte is full, than zeroize counter and get new byte
            count = 0;
            byte = inputArchive.get();
        }
    }
 
    inputArchive.close();
    outputFile.close();
 
    delete treeRoot; //free up memory
}


Буду всем очень благодарен за подсказки!
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
22.01.2016, 21:25
Ответы с готовыми решениями:

Метод getline(cin, m) не срабатывает без cin.ignore() / Ревью кода
Почему в моем случае getline(cin, m) не срабатывает без cin.ignore() ? Если по коду есть какие-нибудь замечания, то просьба написать что не...

Прошу сделать код ревью с конструктивной критикой
Добрый день! Прошу покритиковать код. https://www43.zippyshare.com/v/OoX5wDpx/file.html

Проведите ревью кода?
Посмотрите, пожалуйста, код - не прошёл испытательный срок - жалуются на качество. Всё ли так плохо? using...

3
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
22.01.2016, 21:43
1.
source_file.cpp: In function ‘void archive()’:
source_file.cpp:171:27: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
for (int i = 0; i < bin.size(); i++) {

2.

C++
1
2
3
4
5
Node (Node *L, Node *R){ //constructor takes a reference to the left and right son
        left = L;
        right = R;
        number = L->number + R->number; //the sum of two nodes values
    }
replace to:

C++
1
2
3
4
5
6
7
8
9
10
11
12
//constructor takes a reference to the left and right son
Node (Node *L, Node *R)
    :left(L)
    ,right(R)
    ,number()
{ 
    assert(left);
    assert(right);
 
    //the sum of two nodes values
    number = L->number + R->number; 
}
(note: use the initialization list)

C++
1
2
3
4
5
struct MyCompare{
    bool operator()(Node* left, Node* right){ //parameters overload
        return left->number < right->number;
    }
};
replace to:

C++
1
2
3
4
5
6
struct MyCompare{
    //parameters overload
    bool operator()(const Node* left, const Node* right){ 
        return left->number < right->number;
    }
};
(note: grammar const)


C++
1
2
3
4
 if (root->left != NULL) {
        code.push_back(0); //put zero in the vector
        symbolCodeAssociation(root->left); //run the function for the left son
    }
(note: Oh! captain Obvious!)

C++
1
2
cin >> choice;
switch (choice) {
(note: warning! danger of security applications)


C++
1
for (map <char, int>::iterator iterator = symbolFrequencyAssociation.begin(); iterator != symbolFrequencyAssociation.end(); ++iterator){
replace it:

C++
1
for (auto i = symbolFrequencyAssociation.begin(); i != symbolFrequencyAssociation.end(); ++i){
(note: use c++1y)

can be continued...
2
5 / 5 / 4
Регистрация: 01.02.2016
Сообщений: 11
01.02.2016, 16:45
Лучший ответ Сообщение было отмечено JavJun как решение

Решение

JavJun, очень не советовал бы использовать reinterpret_cast<char *>
1
12 / 10 / 5
Регистрация: 27.08.2015
Сообщений: 236
03.02.2016, 16:58  [ТС]
iArdelyan, спасибо!) Меня как раз преподаватель в них носом и тыкал...конечно не только в них, но в приведение типов в основном.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
03.02.2016, 16:58
Помогаю со студенческими работами здесь

Ревью небольшого кода
Хаскелл я изучаю совсем недавно, поэтому хотелось бы узнать, что и как можно было написать лучше. Задача такая. Задается входной...

Написал крестики-нолики. Сделайте ревью кода
Добрый день. В качестве изучения C# написал крестики-нолики на основе MVC, но, пока без использования событий и делегатов, а просто...

На собеседовании попросили сделать код ревью
На собеседовании задали вопрос как такой код можно улучшить, оригинал кода удалось сохранить))) Прошу прокомментировать что можно...

На собеседовании попросили сделать код ревью
На собеседовании задали вопрос как такой код можно улучшить, оригинал кода удалось сохранить))) Прошу прокомментировать что можно...

На собеседовании попросили сделать код ревью
На собеседовании задали вопрос: Как такой код можно улучшить, оригинал кода удалось сохранить))) Прошу прокомментировать что...


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

Или воспользуйтесь поиском по форуму:
4
Ответ Создать тему
Новые блоги и статьи
Символьное дифференцирование
igorrr37 13.02.2026
/ * Логарифм записывается как: (x-2)log(x^2+2) - означает логарифм (x^2+2) по основанию (x-2). Унарный минус обозначается как ! */ #include <iostream> #include <stack> #include <cctype>. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL3_image
8Observer8 10.02.2026
Содержание блога Библиотека SDL3_image содержит инструменты для расширенной работы с изображениями. Пошагово создадим проект для загрузки изображения формата PNG с альфа-каналом (с прозрачным. . .
Установка Qt-версии Lazarus IDE в Debian Trixie Xfce
volvo 10.02.2026
В общем, достали меня глюки IDE Лазаруса, собранной с использованием набора виджетов Gtk2 (конкретно: если набирать текст в редакторе и вызвать подсказку через Ctrl+Space, то после закрытия окошка. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru