Guest User

Untitled

a guest
Apr 20th, 2018
237
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.66 KB | None | 0 0
  1. #define _CRT_SECURE_NO_WARNINGS
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5.  
  6. typedef struct Tree_t {//дерево
  7. char data;
  8. int weight;
  9. char str[256];
  10. struct Tree_t *left;
  11. struct Tree_t *right;
  12. }tree;
  13.  
  14. typedef struct code_t { //структура для вывода дерева.
  15. unsigned long long code;
  16. int len;
  17. }code_s;
  18.  
  19. unsigned char codes[256]; //для составления кода, во время обхода
  20. int all_len;//не используется
  21. unsigned char last_code; //сам код
  22. int len_last_code; //длина последнего кода (для write_bit)
  23. FILE *fout = fopen("out.txt", "wb");
  24. int global;//для отладки
  25.  
  26. typedef struct queue_t { //Эта структура для слияния
  27. tree *tree;
  28. struct queue_t *next;
  29. }queue;
  30.  
  31. tree *merge(tree *l, tree *r) { //слияние деревьев
  32. tree *new_tr = (tree*)calloc(1, sizeof(tree));
  33. new_tr->weight = l->weight + r->weight;
  34. new_tr->left = l;
  35. new_tr->right = r;
  36. return new_tr;
  37. }
  38.  
  39. queue *enqueue(queue *head, tree *tree_t) { //добавление элемента в очередь с приоритетом
  40. queue *first, *second;
  41. queue *new_el = (queue*)calloc(1, sizeof(queue));
  42. new_el->tree = tree_t;
  43. new_el->next = NULL;
  44.  
  45. if (head == NULL)
  46. return new_el;
  47. first = head;
  48. second = head->next;
  49.  
  50. if (new_el->tree->weight <= first->tree->weight) {
  51. new_el->next = first;
  52. return new_el;
  53. }
  54. else {
  55. while (second) {
  56. if (new_el->tree->weight <= second->tree->weight)
  57. break;
  58. first = second;
  59. second = first->next;
  60. }
  61. first->next = new_el;
  62. new_el->next = second;
  63. return head;
  64. }
  65. }
  66.  
  67. queue *build_haff_tree(queue *head) { //Строим дерево Хаффмана. Голову возвращаем, т.к. она может меняться в процессе
  68. queue *first = NULL, *second = NULL, *new_head = NULL;
  69. queue *tmp = head;
  70. tree *buf;
  71.  
  72. first = tmp;
  73. second = tmp->next;
  74. new_head = second->next;
  75.  
  76. buf = merge(first->tree, second->tree);
  77. head = enqueue(new_head, buf);
  78. free(first); free(second); //Удаляем элементы, которые уже вхоядт в новое дерево
  79. return head;
  80. }
  81.  
  82. queue *create_start_tree(int *ascii, queue *head) { //создаем начальное дерево
  83. int i = 0;
  84. for (i = 0; i <= 255; i++) {
  85. if (ascii[i] != 0) {
  86. tree *new_tr = (tree*)calloc(1, sizeof(tree));
  87. new_tr->data = i;
  88. new_tr->weight = ascii[i];
  89. head = enqueue(head, new_tr);
  90. }
  91. }
  92. return head;
  93. }
  94.  
  95. void clear_tree(tree *tree) {//удаление дерева
  96. if (tree == NULL) { return; }
  97.  
  98. clear_tree(tree->left);
  99. clear_tree(tree->right);
  100. free(tree);
  101. }
  102.  
  103. void input_ascii(FILE *fin, int *ascii) { //заполняем таблицу частоты
  104. while (!feof(fin)) {
  105. ascii[fgetc(fin)]++;
  106. }
  107. }
  108. void input_code_len(char **ascii, char *ascii_len) { //заполняем таблицу длины кодов
  109. for (int i = 0; i < 256; i++) {
  110. if (ascii[i] != NULL)
  111. ascii_len[i] = strlen(ascii[i]);
  112. }
  113. }
  114.  
  115. void write_bit(code_s code, unsigned char sumbol) {//записываем дерево
  116. int i = 0;
  117. unsigned char out_bit = 0;
  118. unsigned char out_sumbol = 0;
  119. if (len_last_code != 0)
  120. i = len_last_code;
  121. out_bit = (128 >> (code.len + len_last_code));
  122. while (i <= code.len + len_last_code) {
  123. i++;
  124. if (i == 8) {
  125. out_sumbol = out_bit | last_code;
  126. fprintf(fout, "%c", out_sumbol);
  127. code.len = code.len - (8 - len_last_code);
  128. len_last_code = 0;
  129. i = 0;
  130. out_bit = 0;
  131. out_bit = (128 >> (code.len + len_last_code));
  132. global++;
  133. }
  134. }
  135.  
  136. out_sumbol = out_bit | (sumbol >> i);
  137. fprintf(fout, "%c", out_sumbol);
  138. last_code = (sumbol << (8 - i));
  139. len_last_code = i;
  140. global++;
  141. return;
  142. }
  143.  
  144. void write_tree_haffman(tree *tree, FILE *tree_out, char **ascii, code_s code) { //Составляем таблицу и записываем дерево в файл
  145. if ((tree->left == NULL) && (tree->right == NULL)) {
  146. tree->weight = strlen(tree->str);
  147. codes[tree->data] = code.code;
  148. if (codes[tree->data] != codes[0])
  149. write_bit(code, tree->data);
  150. return;
  151. }
  152. else {
  153. code_s c = code;
  154. c.code = (1 << c.len);
  155. c.len++;
  156. all_len++;
  157. strcpy(tree->left->str, tree->str);
  158. ascii[tree->left->data] = tree->left->str;
  159. tree->weight = strlen(tree->str);
  160. tree->left->str[tree->weight] = '0';
  161. write_tree_haffman(tree->left, tree_out, ascii, c);
  162. strcpy(tree->right->str, tree->str);
  163. ascii[tree->right->data] = tree->right->str;
  164. tree->right->str[tree->weight] = '1';
  165. write_tree_haffman(tree->right, tree_out, ascii, c);
  166. }
  167. }
  168.  
  169. void print_text(FILE *fin, FILE *fout, char **ascii, char *ascii_len) { //переводим текст в код хаффмана
  170. char c;
  171. int last_len = 0;
  172. unsigned char out = 0;
  173. char *tmp;
  174. while (fscanf(fin, "%c", &c) != -1) {
  175. tmp = ascii[c];
  176. for (int j = 0; j < ascii_len[c]; j++) {
  177. last_len++;
  178. if (tmp[j] == '1')
  179. out = out | (1 << (8 - last_len));
  180. if (last_len == 8) {
  181. fprintf(fout, "%c", out);
  182. out = 0;
  183. last_len = 0;
  184. }
  185. }
  186. }
  187. }
  188.  
  189. int main() {
  190. int ascii[260] = { 0 };
  191. char *ascii_code[260] = { NULL };
  192. char len_code[260] = { 0 };
  193. char c = 0;
  194. queue *head = NULL;
  195. queue *tmp_head = NULL;
  196. tree *tree_h = NULL;
  197. code_s code;
  198. code.code = 0;
  199. code.len = 0;
  200. global = 0;
  201.  
  202. FILE *fin = fopen("in.txt", "rb");
  203. fscanf(fin, "%c", &c);
  204.  
  205. input_ascii(fin, ascii); //заполняем массив частоты элементов
  206. head = create_start_tree(ascii, head); //создаем первые узлы и кидаем их в очередь с их приоритетом
  207. tmp_head = head;
  208.  
  209. while (head->next != NULL)
  210. head = build_haff_tree(head); //создаем дерево Хаффмана
  211.  
  212. tree_h = head->tree;
  213. tree_h->str[0] = 0;
  214. fseek(fin, 2, SEEK_SET);
  215. write_tree_haffman(tree_h, fout, ascii_code, code);
  216. if (len_last_code != 0)
  217. fprintf(fout, "%c", last_code);
  218. input_code_len(ascii_code, len_code);
  219. //print_text(fin, fout, ascii_code, len_code);
  220. fclose(fin); fclose(fout);
  221. return 0;
  222. }
Add Comment
Please, Sign In to add comment