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

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

22.01.2016, 21:25. Показов 1264. Ответов 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
Ответ Создать тему
Новые блоги и статьи
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка. Рецензия / Мнение Это мой обзор планшета X220 с точки зрения школьника. Недавно я решила попытаться уменьшить свой. . .
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
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru