Advertisement
wurdalak007

Huffman d/w

Nov 22nd, 2017
83
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.17 KB | None | 0 0
  1. #include <iostream>
  2. #include <array>
  3. #include <string>
  4. #include <queue>
  5. #include "Huffman.h"
  6.  
  7.  
  8. typedef char byte;
  9. using namespace std;
  10.  
  11. struct list {
  12. int repeat = 0;
  13. byte symb;
  14. string code;
  15. list* left = nullptr;
  16. list* right = nullptr;
  17. };
  18.  
  19. bool operator <( list first, list second ){
  20. return first.repeat > second.repeat;
  21. }
  22.  
  23. void init_arr( array<list, 258>& ASCII ) {
  24. for( int i = 0; i < 256; i++){
  25. ASCII[i].repeat = 0;
  26. ASCII[i].symb =(byte)(i);
  27. }
  28. }
  29.  
  30. void generateCode( list*& root ) {
  31. if( root == nullptr ) {
  32. return;
  33. }
  34. if( root->left != nullptr ) {
  35. root->left->code = root->code + '0';
  36. }
  37. if( root->right != nullptr ) {
  38. root->right->code = root->code + '1';
  39. }
  40.  
  41. generateCode(root->left);
  42. generateCode(root->right);
  43. }
  44.  
  45. void translate( list* root, vector<list*>& shedule ) {
  46.  
  47. if( root->right == nullptr && root->left == nullptr ) {
  48. shedule.push_back(root);
  49. return;
  50. } else {
  51. translate(root->left, shedule);
  52. translate(root->right, shedule);
  53. }
  54. }
  55.  
  56. string find_code( vector<list*> shed, byte p) {
  57. int i = 0;
  58. while( (shed[i]->symb != p)&&( p != '\n') ) {
  59. i++;
  60. }
  61. return shed[i]->code;
  62. }
  63.  
  64. string into_bin ( byte p ) {
  65. string binary;
  66. int p_num = (int)p;
  67. int i = 0;
  68.  
  69. while( p_num > 0 ) {
  70. p_num /= 2;
  71. i++;
  72. }
  73. p_num = (int)p;
  74. i--;
  75. for( ; i >= 0; --i ) {
  76. if( 0 == ((p_num>>i)&(0x1)) ) {
  77. binary += '0';
  78. } else {
  79. binary += '1';
  80. }
  81. }
  82.  
  83. return binary;
  84.  
  85. }
  86.  
  87. void crypt_tree( vector<list*>& shedule, string& crypt ) {
  88.  
  89. for( int i = 0; i < shedule.size(); i++ ) {
  90. crypt += into_bin(shedule[i]->symb);
  91. crypt += ' ';
  92. crypt += shedule[i]->code;
  93. crypt += ' ';
  94. }
  95.  
  96. }
  97.  
  98. void Encode( IInputStream& input, IOutputStream& compressed ) {
  99. array<list, 258> ASCII;
  100. init_arr( ASCII );
  101. byte symb;
  102. string input_str;
  103. while(input.Read(symb)){
  104. ASCII[(int)symb].repeat += 1;
  105. input_str += symb;
  106. }
  107.  
  108. vector<list*> shedule;
  109. priority_queue<list> queue;
  110. for( int i = 0; i < 256; i++ ) {
  111. if( ASCII[i].repeat != 0 ) {
  112. queue.push(ASCII[i]);
  113. }
  114. }
  115.  
  116. while( queue.size() >= 2) {
  117. list* tmp1 = new list( queue.top() );
  118. queue.pop();
  119. list* tmp2 = new list( queue.top() );
  120. queue.pop();
  121.  
  122. list* newtmp = new list;
  123. newtmp->left = tmp1;
  124. newtmp->right = tmp2;
  125. newtmp->repeat = tmp1->repeat + tmp2->repeat;
  126. queue.push(*(newtmp));
  127. }
  128.  
  129. list* root = new list( queue.top() );
  130. root->code = '1';
  131. root->left->code = "0";
  132. root->right->code = "1";
  133. generateCode(root->right);
  134. generateCode(root->left);
  135. translate( root, shedule );
  136.  
  137. string output;
  138. crypt_tree(shedule, output);
  139.  
  140. for( int i = 0; i < input_str.length(); i++ ){
  141. output += find_code(shedule, input_str[i]);
  142. }
  143. for(auto i : output){
  144. compressed.Write(i);
  145. }
  146.  
  147. }
  148.  
  149. list* decode_tree ( string output, int& position ) {
  150. list* root = new list;
  151. list* tmp = root;
  152. int symb_num = 0;
  153. int j = 0;
  154. int i = 0;
  155.  
  156. while( i < output.length() ) {
  157. for(; output[i] != ' '; i++ ) {
  158. j++;
  159. symb_num = symb_num*2 + (output[i] - '0' )*2;
  160. if( symb_num >= 256 ) {
  161. position = i - j + 1;
  162. return root;
  163. }
  164. }
  165. symb_num /= 2;
  166. j = 0;
  167. i++;
  168. while( output[i] != ' ') {
  169. if( output[i] == '1' ) {
  170. if( tmp->right == nullptr) {
  171. list* right = new list;
  172. tmp->right = right;
  173. right->code = tmp->code + '1';
  174. tmp = right;
  175. i++;
  176. } else {
  177. tmp = tmp->right;
  178. i++;
  179. }
  180. } else {
  181. if( tmp->left == nullptr ) {
  182. list* left = new list;
  183. tmp->left = left;
  184. left->code = tmp->code + '0';
  185. tmp = left;
  186. i++;
  187. } else {
  188. tmp = tmp->left;
  189. i++;
  190. }
  191. }
  192. }
  193. tmp->symb = (byte)symb_num;
  194. tmp = root;
  195. i++;
  196. symb_num = 0;
  197. }
  198. return root;
  199. }
  200.  
  201. void Decode( IInputStream& compressed, IOutputStream& input ) {
  202. int position = 0;
  203. string output;
  204. byte symb;
  205.  
  206. while( compressed.Read(symb) ) {
  207. output += symb;
  208. }
  209.  
  210. list* root = decode_tree( output, position );
  211. list* tmp = new list;
  212. tmp = root;
  213.  
  214. for( int i = position; i < output.length(); i++ ) {
  215. if( output[i] == '0' ) {
  216. if( tmp->left == nullptr ) {
  217. input.Write(tmp->symb);
  218. tmp = root;
  219. }
  220. tmp = tmp->left;
  221. } else {
  222. if( tmp->right == nullptr) {
  223. input.Write(tmp->symb);
  224. tmp = root;
  225.  
  226. }
  227. tmp = tmp->right;
  228. }
  229. }
  230. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement