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

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Izanaki
0 / 0 / 0
Регистрация: 13.12.2014
Сообщений: 2
#1

Архиватор Хаффмана не распаковывает двойное сжатие - C++

06.04.2016, 11:53. Просмотров 215. Ответов 0
Метки нет (Все метки)

Привет всем. Тут такое дело. Написал архиватор Хаффмана. Вроде работает, но если сжать второй раз а потом попытаться распаковать циклится. В чем может быть проблема?
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
union code {
    unsigned char chh;
    struct byte{
        unsigned b1 : 1;
        unsigned b2 : 1;
        unsigned b3 : 1;
        unsigned b4 : 1;
        unsigned b5 : 1;
        unsigned b6 : 1;
        unsigned b7 : 1;
        unsigned b8 : 1;
    } byte;
};
 
void nn(string path) {
    code code1;
    Node_mas nodess;
    ifstream file1;
    ofstream file2;
    string binary_code;
    char buff;
    file1.open(path, ios::binary);
    while (true) {
        file1.get(buff);
        if (file1.eof()) break;
        nodess.sravn(buff);
    }
    file1.close();
    file1.open("C:\\Users\\Izanaki\\Desktop\\Test\\testing.txt", ios::binary);
    while (true) {
        if (path.back() == '\\')
            break;
        else path.pop_back();
    }
    nodess.save_tree(path + "t.txt");
    nodess.create_tree();
    while (true) {
        file1.get(buff);
        if (file1.eof()) break;
        binary_code += nodess.encrypt(buff);
    }
    file2.open(path + "t.txt", ios::binary | ios::app);
    file2 << '/';
    for (int i = 0; i < binary_code.length() / 8; i++) {
        code1.byte.b1 = binary_code[8 * i + 0] - '0';
        code1.byte.b2 = binary_code[8 * i + 1] - '0';
        code1.byte.b3 = binary_code[8 * i + 2] - '0';
        code1.byte.b4 = binary_code[8 * i + 3] - '0';
        code1.byte.b5 = binary_code[8 * i + 4] - '0';
        code1.byte.b6 = binary_code[8 * i + 5] - '0';
        code1.byte.b7 = binary_code[8 * i + 6] - '0';
        code1.byte.b8 = binary_code[8 * i + 7] - '0';
        file2 << code1.chh;
    }
    bool b1 = true; code1.byte.b1 = 0;
    bool b2 = true; code1.byte.b2 = 0;
    bool b3 = true; code1.byte.b3 = 0;
    bool b4 = true; code1.byte.b4 = 0;
    bool b5 = true; code1.byte.b5 = 0;
    bool b6 = true; code1.byte.b6 = 0;
    bool b7 = true; code1.byte.b7 = 0;
    bool b8 = true; code1.byte.b8 = 0;
    for (int i = binary_code.length() / 8 * 8; i < binary_code.length(); i++) {
        if (b1) { code1.byte.b1 = binary_code[i] - '0'; b1 = false; continue; }
        if (b2) { code1.byte.b2 = binary_code[i] - '0'; b2 = false; continue; }
        if (b3) { code1.byte.b3 = binary_code[i] - '0'; b3 = false; continue; }
        if (b4) { code1.byte.b4 = binary_code[i] - '0'; b4 = false; continue; }
        if (b5) { code1.byte.b5 = binary_code[i] - '0'; b5 = false; continue; }
        if (b6) { code1.byte.b6 = binary_code[i] - '0'; b6 = false; continue; }
        if (b7) { code1.byte.b7 = binary_code[i] - '0'; b7 = false; continue; }
        if (b8) { code1.byte.b8 = binary_code[i] - '0'; b8 = false; continue; }
    }
    cout << binary_code << endl << endl;
    file2 << code1.chh;
    file2.close();
}
void dc(string path) {
    code code1;
    Node_mas nodess;
    ifstream file1;
    ofstream file2;
    string contest;
    string binary_code;
    char buff;
    nodess.restore_tree(path);
    file1.open(path, ios::binary);
    nodess.create_tree();
    while (true) {
        file1.get(buff);
        if (file1.eof() || buff == '/') break;
    }
    while (true) {
        file1.get(buff);
        if (file1.eof()) break;
        contest += buff;
    }
    file1.close();
    while (true) {
        if (path.back() == '\\')
            break;
        else path.pop_back();
    }
    file2.open(path + "tas.txt", ios::binary);
    for (int i = 0; i < contest.length(); i++) {
        code1.chh = contest[i];
        binary_code.push_back(code1.byte.b1 + '0');
        binary_code.push_back(code1.byte.b2 + '0');
        binary_code.push_back(code1.byte.b3 + '0');
        binary_code.push_back(code1.byte.b4 + '0');
        binary_code.push_back(code1.byte.b5 + '0');
        binary_code.push_back(code1.byte.b6 + '0');
        binary_code.push_back(code1.byte.b7 + '0');
        binary_code.push_back(code1.byte.b8 + '0');
    }
    while (true) {
        if (binary_code.back() != '1') binary_code.pop_back();
        else break;
    }
    cout << binary_code;
    file2 << nodess.decrypt(binary_code);
    file2.close();
}
void main() {
    setlocale(LC_ALL,"RUS");
    nn("C:\\Users\\Izanaki\\Desktop\\Test\\testing.txt");
    dc("C:\\Users\\Izanaki\\Desktop\\Test\\t.txt");
    system("pause");
}
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
#include <vector>
#include <string>
#include <fstream>
using namespace std;
//Элемент дерева
struct Node{
    //Конструктор
    Node(char ch_ = '0', int weigt_ = 0, Node* left_ = NULL, Node* right_ = NULL, Node* parent_ = NULL) {
        ch = ch_;
        weigt = weigt_;
        left = left_;
        right = right_;
        parent = parent_;
    }
    //Конструктор копирования
    Node(Node &ptr_) {
        ch = ptr_.ch;
        weigt = ptr_.weigt;
        left = ptr_.left;
        right = ptr_.right;
        parent = ptr_.parent;
    }
    //Символ
    char ch;
    //Вес
    int weigt;
    //Указатель на левого потомка
    Node* left;
    //Указатель на правого потомка
    Node* right;
    //Указатель на родителя
    Node* parent;
};
//Дерево
string buffs;
class Node_mas {
    //Массив из указателей на элементы
    vector <Node*> nodes;
public:
    //Проверка наличия элемента в массиве
    void sravn(char symb_) {
        //Если нету элементов, добавляем новый символ и устанавливаем количество 1
        if (nodes.size() == 0) {
            nodes.push_back(new Node(symb_, 1));
            return;
        }
        //Проверка и наращивание элемента
        //Если есть символ, наращиваем его количество
        for (int i = 0; i < nodes.size(); i++) {
            if (nodes.at(i)->ch == symb_) {
                nodes.at(i)->weigt++;
                return;
            }
        }
        //Иначе добавляем новый
        nodes.push_back(new Node(symb_, 1));
    }
    //Построение дерева
    void create_tree() {
        //Вычисляем сумму всех весов
        int sum = 0;
        int i = 0;
        for (int i = 0; i < nodes.size(); i++)
            sum += nodes.at(i)->weigt;
        //Пока новый элемент не равен сумме всех весов, соединяем элементы
        while (summ(i) < sum) {
            i += 2;
        }
    }
    //Зашифровка символа
    string encrypt(char symb_) {
        string buff;
        for (int i = 0; i < nodes.size(); i++) {
            if (nodes.at(i)->ch == symb_) {
                Node* node = nodes.at(i);
                while (node->parent != NULL) {
                    if (node->parent->left == node)
                        buff += "0";
                    else
                        buff += "1";
                    node = node->parent;
                }
            }
        }
        //Инвертируем строку
        string obr;
        for (int i = buff.length() - 1; i > -1; i--) {
            obr+= buff[i];
        }
        return obr;
    }
    //Дешифровка последовательности битов
    string decrypt(string str_) {
        Node* ptr = nodes.back();
        string result;
        for (int i = 0; i < str_.length(); i++) {
            if (str_.at(i) == '0') {
                if (ptr->left == NULL) {
                    result.push_back(ptr->ch);
                    ptr = nodes.back();
                }
                ptr = ptr->left;
            }
            else {
                if (ptr->right == NULL) {
                    result.push_back(ptr->ch);
                    ptr = nodes.back();
                }
                ptr = ptr->right;
            }
        }
        return result;
    }
    void show() {
        int i = 0;
        while (i < nodes.size()) {
            if (nodes.at(i)->ch == NULL)
                cout << "Empty!" << " ";
            else
                cout << nodes.at(i)->ch << " ";
            cout << nodes.at(i)->weigt << " ";
            if (nodes.at(i)->left == NULL)
                cout << "Empty!" << " ";
            else
                cout << nodes.at(i)->left->weigt << " ";
            if (nodes.at(i)->right == NULL)
                cout << "Empty!" << " ";
            else
                cout << nodes.at(i)->right->weigt << " ";
            if (nodes.at(i)->parent == NULL)
                cout << "Empty!" << " ";
            else
                cout << nodes.at(i)->parent->weigt << " ";
            cout << endl;
            if (nodes[i]->ch == '\r') cout << "\r";
            if (nodes[i]->ch == '\n') cout << "\n";
            i++;
        }
    }
    void save_tree(string path) {
        ofstream file;
        file.open(path, ios::binary);
        for (int i = 0; i < nodes.size(); i++) {
            if (nodes.at(i)->ch == NULL) continue;
            file.put(nodes.at(i)->ch);
            file << nodes.at(i)->weigt;
        }
        file.close();
    }
    //Восстановление дерева
    void restore_tree(string path) {
        ifstream file;
        char buff;
        file.open(path, ios::binary);
        while (true) {
            Node* node = new Node();
            file.get(node->ch);
            file >> node->weigt;
            if (node->ch == '/') break;
            nodes.push_back(node);
        }
        file.close();
    }
private:
    //Сортировка по возрастанию
    void sort() {
        for (int i = 0; i < nodes.size() - 1; i++) {
            for (int j = 0; j < nodes.size() - i - 1; j++) {
                if (nodes.at(j)->weigt > nodes.at(j + 1)->weigt) {
                    Node* buff = nodes.at(j);
                    nodes[j] = nodes[j + 1];
                    nodes[j + 1] = buff;
                }
            }
        }
    }
    //Слияние двух элементов с позиции i в один новый 
    int summ(int i) {
        //if (nodes.size() == 0 && nodes.size() == 1)
        sort();
        nodes.push_back(new Node(NULL, nodes[i]->weigt + nodes[i + 1]->weigt, nodes[i], nodes[i + 1], NULL));
        nodes.at(i)->parent = nodes.back();
        nodes.at(i + 1)->parent = nodes.back();
        int result = nodes.at(i)->weigt + nodes.at(i + 1)->weigt;
        return result;
    }
};
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
06.04.2016, 11:53
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Архиватор Хаффмана не распаковывает двойное сжатие (C++):

Архиватор Хаффмана c++ - C++
Пишу архиватор на c++ методом Хаффмана. Не могу найти как считывать байты из файла в c++.

Написать архиватор на основе метода Хаффмана - C++
Вот собственно задача состоит в том что нужно написать программу(архиватор) основываясь на методе Хаффмана. Что нужно знать и на чём нужно...

Сжатие Хаффмана - C++
Есть прога, реализующая сжатие Хаффмана: #include &quot;stdafx.h&quot; #include &lt;iostream&gt; #include &lt;vector&gt; #include &lt;map&gt; #include...

Сжатие Хаффмана - C++
Как изменить данный алгоритм, чтобы ограничить длину кода символа заданным числом Nmax? Спасибо! #include &quot;stdafx.h&quot; #include...

Реализовать свой собственный архиватор по алгоритму хаффмана - C#
Хочу реализовать свой собственный архиватор по алгоритму хаффмана, но есть проблема, допустим я считываю с txt файла где каждый символ...

Архиватор , в основе которого будет лежать алгоритм Хаффмана - Delphi
Итак, приветствую всех=) случилась у меня беда, дали вот такую весёлую&quot; тему для курсача =)(не спрашивайте почему не выбрал другую, как и...

0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
06.04.2016, 11:53
Привет! Вот еще темы с ответами:

Архиватор на основе алгоритма Хаффмана, помогите разобрать код. - Delphi
Всем привет :) вот в чем собственно вопрос или просьба... мне задана курсовая работа &quot;Архиватор на основе алгоритма Хаффама&quot;. Что у...

Максимальное сжатие каталога через консольный архиватор 7z - CMD/BAT
Необходимо максимально сжать каталог через консольный архиватор 7z. Через GUI настройки см. в архиве, а как эти параметры прописать в...

Сжатие данных алгоритмом Хаффмана - C#
Вопрос заключается в том какими классами пользуетесь для хранения битов. т.е мы знаем что буква А кодируется 4-мя битами 1100, буква B -...

Сжатие данных методом Хаффмана - Delphi
надо прогу сделать... самую простейшую... Задача: вводишь строку символов (можно ограничиться 50 символами думаю), программа сжимает...


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

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

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