1
+ #include < bits/stdc++.h>
2
+
3
+ using namespace std ;
4
+
5
+ struct pixel {
6
+ int freq;
7
+ int label;
8
+ pixel* left, *right;
9
+
10
+ pixel (int x, int y): label(x), freq(y){
11
+ left = NULL ;
12
+ right = NULL ;
13
+ }
14
+
15
+ void print (){
16
+ cout << label << " " << freq << endl;
17
+ }
18
+ };
19
+
20
+ struct huffcode {
21
+ int label;
22
+ int parent;
23
+ string code;
24
+ };
25
+
26
+ struct compare {
27
+ bool operator () (pixel* a, pixel* b){
28
+ return a->freq > b->freq ;
29
+ }
30
+ };
31
+
32
+ ofstream out (" huffman.txt" );
33
+
34
+ huffcode codes[256 ];
35
+
36
+ void preoder (pixel* root, string s, int level, int parent){
37
+
38
+ if (root->label < 256 ){
39
+ // if(level >= 3){
40
+ // codes[root->label].parent = parent;
41
+ // }
42
+ // else{
43
+ // codes[root->label].parent = -1;
44
+ // }
45
+ codes[root->label ].parent = parent;
46
+ codes[root->label ].code = s;
47
+ cout << setfill (' ' ) << setw (3 ) << root->label
48
+ << " -> " << setw (7 ) << s << setw (4 ) << codes[root->label ].parent << endl;
49
+ return ;
50
+ }
51
+
52
+ out << root->label << " -> " << root->left ->label << " [ label = \" " << s+' 0' << " \" ];" <<endl;
53
+ out << root->label << " -> " << root->right ->label << " [ label = \" " << s+' 1' << " \" ];" << endl;
54
+
55
+ if (level == 3 )
56
+ parent = root->label ;
57
+
58
+ preoder (root->left , s + ' 0' , level+1 , parent);
59
+ preoder (root->right , s + ' 1' , level+1 , parent);
60
+
61
+ return ;
62
+ }
63
+
64
+ int main (){
65
+
66
+ // Uploading Image
67
+
68
+ string s;
69
+ cin >> s;
70
+
71
+ int freq[256 ] = {0 };
72
+
73
+ for (auto i: s){
74
+ freq[i] += 1 ;
75
+ }
76
+
77
+ priority_queue<pixel*, vector<pixel*>, compare> pq;
78
+
79
+ for (int i = 0 ; i < 256 ; i++){
80
+ if (freq[i] > 0 ){
81
+ pixel* tmp = new pixel (i, freq[i]);
82
+ pq.push (tmp);
83
+ }
84
+ }
85
+
86
+ int cnt = 256 ;
87
+
88
+ while (pq.size () > 1 ){
89
+ pixel* first = pq.top ();
90
+ pq.pop ();
91
+ pixel* second = pq.top ();
92
+ pq.pop ();
93
+ pixel* tmp = new pixel (cnt++, first->freq + second->freq );
94
+ tmp->left = first;
95
+ tmp->right = second;
96
+ pq.push (tmp);
97
+ }
98
+
99
+ pixel* root = pq.top ();
100
+
101
+ out << " digraph{" << endl;
102
+
103
+ preoder (root, " " , 0 , -1 );
104
+
105
+ out << " }" << endl;
106
+
107
+ // string str = "dot -Tpng huffman.txt -o huffman.png"; // running dot file through terminal
108
+ // const char *command = str.c_str(); // system function is copied from https://www.geeksforgeeks.org/system-call-in-c/
109
+ // system(command);
110
+
111
+
112
+ string w;
113
+ int last = -1 ;
114
+ bool f = 0 ;
115
+
116
+ for (int i = 0 ; i < s.length (); i++){
117
+ if (f == 0 ){
118
+ w += codes[s[i]].code ;
119
+ }
120
+ else if (codes[s[i]].parent == codes[last].parent ){
121
+ w += ' 1' ;
122
+ string code = codes[s[i]].code ;
123
+ w += code.substr (3 , code.length ());
124
+ }
125
+ else {
126
+ w += ' 0' ;
127
+ w += codes[s[i]].code ;
128
+ }
129
+ if (codes[s[i]].parent == -1 )
130
+ f = 0 ;
131
+ else {
132
+ last = s[i];
133
+ f = 1 ;
134
+ }
135
+ }
136
+
137
+ cout << w << endl;
138
+ cout << w.length () << " " << s.length () * 4 << endl;
139
+
140
+ return 0 ;
141
+ }
0 commit comments