Advertisement
wurdalak007

хуфман

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