-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathEncode.cpp
145 lines (104 loc) · 3.1 KB
/
Encode.cpp
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
#include "Encode.h"
#include <algorithm>
#include <iostream>
#include <bitset>
bool comparePair(my_pair i1, my_pair i2){
if(i1.second < i2.second)
return true;
else if(i1.second == i2.second){
return i1.first < i2.first;
}
return false;
}
string Encode::getEncoding(){
string encoded;
for(char c: plaintext){
encoded += this->encoding[c];
}
return encoded;
}
Data Encode::getEncodingBinary(){
string encoded;
for(char c: plaintext){
encoded += this->encoding[c];
}
const uint32_t str_length = encoded.length();
this->padding = 0;
//Encoded text is not multiple of 8 bits
if((str_length % 8) != 0){
this->padding = 8 - (str_length % 8);
for(uint32_t i=0;i<padding;i++)
encoded += "0";
}
const uint32_t padded_str_length = encoded.length();
Data d(padded_str_length/8);
uint32_t index = 0;
uint8_t *ptr = &d.data[0];
while(index < padded_str_length){
*ptr = (uint8_t)bitset<8>(encoded,index,8).to_ulong();
ptr++;
index += 8;
}
return d;
}
my_queue Encode::count_occurencies(){
my_map dictionary(256); //already initialized to 0; 255 for 8 bit
for (const char &c: plaintext) {
dictionary[c]++;
}
my_queue sorted;
for (auto &e: dictionary) {
leaf *f = new leaf(e.first,e.second);
sorted.push(f);
}
return sorted;
}
void Encode::generate_huffmann_code(my_queue &occorrenze){
while(occorrenze.size() > 1){
leaf *uno = occorrenze.top();
occorrenze.pop();
leaf *due = occorrenze.top();
occorrenze.pop();
leaf *parent = new leaf;
parent->left = uno;
parent->right = due;
parent->value = uno->value + due->value;
occorrenze.push(parent);
}
leaf *root = occorrenze.top();
occorrenze.pop();
get_encoding_length_and_free(root,0);
generate_huffman_canonical();
}
void Encode::generate_huffman_canonical(){
sort(this->vector_encoding_length.begin(), this->vector_encoding_length.end(), comparePair);
uint64_t counter =0;
uint64_t old_bitlen = vector_encoding_length[0].second;
for (const auto &x : this->vector_encoding_length){
//first increment then shift to the left
counter = counter << (x.second - old_bitlen);
this->encoding[x.first] = numberToBitString(counter,x.second);
counter = (counter + 1);
old_bitlen = x.second;
}
}
void Encode::get_encoding_length_and_free(leaf *node, uint64_t length){
if(node == nullptr)
return;
if(node->left == nullptr && node->right == nullptr){
my_pair p(node->key,length);
this->vector_encoding_length.push_back(p);
delete node;
return;
}
get_encoding_length_and_free(node->left,length+1);
get_encoding_length_and_free(node->right,length+1);
delete node;
}
void Encode::print_queue(my_queue sorted){
while (!sorted.empty()){
leaf *p = sorted.top();
cout<<p->key<<" '"<<p->value<<"'"<<endl;
sorted.pop();
}
}