bogdan2004333

Untitled

Dec 16th, 2022
98
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 12.66 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4.  
  5. typedef struct counter_pair {
  6.     char new_symb_code[30];
  7.     char symb_code[30];//двоичный код символа
  8.     int count;// сколько раз символ встретился
  9.     struct counter_pair *left;
  10.     struct counter_pair *right;
  11. } table;
  12.  
  13. table *make_tree(table *psym[], int k)//рeкурсивная функция создания дерева Хофмана
  14. {
  15.     table *temp = malloc(sizeof(table));
  16.     temp->count = psym[k - 1]->count + psym[k - 2]->count;
  17.     temp->new_symb_code[0] = 0;
  18.     temp->left = psym[k - 1];
  19.     temp->right = psym[k - 2];
  20.  
  21.     if (k == 2)
  22.         return temp;
  23.     else //внесение в массив в нужное место элемента дерева Хофмана
  24.     {
  25.         for (int i = 0; i < k; i++)
  26.             if (temp->count > psym[i]->count) {
  27.                 for (int j = k - 1; j > i; j--)
  28.                     psym[j] = psym[j - 1];
  29.  
  30.                 psym[i] = temp;
  31.                 break;
  32.             }
  33.     }
  34.     return make_tree(psym, k - 1);
  35. }
  36.  
  37. void clear(table *dictf,
  38.                 int size) { ///очистка указателей в массиве от мусора(нужна для того, чтобы в void recode не передавались
  39.     for (int i = 0; i < size; i++) { ///указатели на несуществующие узлы(структуры))
  40.         dictf[i].left = 0;
  41.         dictf[i].right = 0;
  42.         dictf[i].new_symb_code[0] = 0;
  43.     }
  44. }
  45.  
  46. void make_code(table *root)//Рекурсивная функция кодирования
  47. {
  48.     if (root->left) {
  49.         strcpy(root->left->new_symb_code, root->new_symb_code);
  50.         strcat(root->left->new_symb_code, "0");
  51.         if (root->left->count > 0) make_code(root->left);
  52.     }
  53.     if (root->right) {
  54.         strcpy(root->right->new_symb_code, root->new_symb_code);
  55.         strcat(root->right->new_symb_code, "1");
  56.         if (root->right->count > 0) make_code(root->right);
  57.     }
  58. }
  59.  
  60. //функция для сортировки статистики
  61. void sort(table numbers[], int n) {
  62.     for (int i = 0; i < n; i++) {
  63.         for (int j = 0; j < n - i - 1; j++) {
  64.             if (numbers[j].count < numbers[j + 1].count) {
  65.                 table temp = numbers[j];
  66.                 numbers[j] = numbers[j + 1];
  67.                 numbers[j + 1] = temp;
  68.             }
  69.         }
  70.     }
  71. }
  72.  
  73. //функция, осуществляющая перевод считанного символа в двоичный код и последующая запись в строку
  74. int DecimalToBinary(int dec, char *s) {
  75.     int bin[50] = {0};
  76.  
  77.     int i = 0;
  78.     while (dec > 0) {       //перевод в двоичную СС
  79.         bin[i] = dec % 2;
  80.         dec = dec / 2;
  81.         ++i;
  82.     }
  83.  
  84.     //записываю двоичный код в строку и переворачиваю
  85.     int bits = 8;
  86.     if (i > 8) {
  87.         bits = 8 * ((i + 7) / 8);
  88.     }
  89.     int n = 0;
  90.     for (int j = bits - 1; j >= 0; j--) {
  91.         n += sprintf((s + n), "%d", bin[j]);
  92.     }
  93.     return dec;
  94. }
  95.  
  96. int count_comp(table *byte, int size, int len) {
  97.     int first = 0;
  98.     int second = 0;
  99.     for (int i = 0; i < size; i++) {
  100.         first += byte[i].count;
  101.         second += (int) (byte[i].count * strlen(byte[i].new_symb_code));
  102.     }
  103.     first *= len;
  104.     printf("Размер до сжатия: %d\nРазмер после сжатия: %d\n", first, second);
  105.     return 0;
  106. }
  107.  
  108. int main() {
  109.     int input;
  110.     printf("Какую статистику хотите получить?(для 8 бит введите 1, для 12 бит введите 2, для 16 бит введите 3, для 20 бит введите 4)\n");
  111.     scanf("%d", &input);
  112.     FILE *text = fopen("text.txt", "r");
  113.     if (!text) {
  114.         printf("Error of file opening.\n");
  115.         return 1;
  116.     }
  117.     //на данном этапе высчитавю количество символов в текстовом файле и задаю количетсво символов при 8 12 16 20 битах соответственно
  118.     fseek(text, 0, SEEK_END);
  119.     int text_lenght = ftell(text);
  120.     int text_lenght1 = (text_lenght * 8) / 12;
  121.     int text_lenght2 = (text_lenght * 8) / 16;
  122.     int text_lenght3 = (text_lenght * 8) / 20;
  123.     fseek(text, 0, SEEK_SET);
  124.     //записываю в структуру коды символов по 8 бит, обнуля счетчик повтора
  125.     if (input == 1) {
  126.         table byte8[256];
  127.         for (int i = 0; i < 256; i++) {
  128.             byte8[i].count = 0;
  129.         }
  130.         table *psym[256];
  131.         int j = 0;
  132.         int flag = 0;
  133.         while (!feof(text)) {
  134.             int k = getc(text);
  135.             char *byte1 = calloc(8, sizeof(char) + 1);
  136.             DecimalToBinary(k, byte1);
  137.             flag = 0;
  138.             for (int i = 0; i < 256; i++) {
  139.                 if (strcmp(byte8[i].symb_code, byte1) == 0) {
  140.                     flag = 1;
  141.                     byte8[i].count += 1;
  142.                 }
  143.  
  144.             }
  145.             if (flag == 0) {
  146.                 strcpy(byte8[j].symb_code, byte1);
  147.                 j++;
  148.             }
  149.         }
  150.         for (int i = 0; i < j; i++) {
  151.             if (byte8[i].count == 0)
  152.                 byte8[i].count += 1;
  153.         }
  154.         for (int i = 0; i < j; i++) //в массив указателей заносим адреса записей
  155.             psym[i] = &byte8[i];
  156.  
  157.         sort(byte8, j);
  158.         clear(byte8, j);
  159.         table *root = make_tree(psym, j);
  160.         make_code(root);
  161.         for (int i = 0; i < j; i++) {
  162.  
  163.             printf("%s - %d   %s\n", byte8[i].symb_code, byte8[i].count, byte8[i].new_symb_code);
  164.         }
  165.         printf("количество символов: %d\n", text_lenght);
  166.         count_comp(byte8, j, 8);
  167.         //записываю в структуру коды символов по 12 бит, обнуля счетчик повтора
  168.     } else if (input == 2) {
  169.         table byte12[4096];
  170.         for (int i = 0; i < 4096; i++) {
  171.             byte12[i].count = 0;
  172.         }
  173.         table *psym[4096];
  174.         int j = 0;
  175.         int flag = 0;
  176.         while (!feof(text)) {
  177.             int b1 = getc(text);
  178.             int b2 = getc(text);
  179.             int b3 = getc(text);
  180.             //сдвигаю первый байт на 4 сдвигаю второй байт на 4 и соединяю их логическим или
  181.             int k = (b1 << 4) | (b2 >> 4);
  182.             //к 3 байту логическим или добавляю последние 4 бита 2 байта
  183.             int k1 = (b3) | ((b2 & 15) << 8);
  184.             char *byte1 = calloc(12, sizeof(char) + 1);
  185.             DecimalToBinary(k, byte1);
  186.             flag = 0;
  187.             for (int i = 0; i < 4096; i++) {
  188.                 if (strcmp(byte12[i].symb_code, byte1) == 0) {
  189.                     flag = 1;
  190.                     byte12[i].count += 1;
  191.                 }
  192.             }
  193.             if (flag == 0) {
  194.                 strcpy(byte12[j].symb_code, byte1);
  195.                 j++;
  196.             }
  197.             byte1 = calloc(12, sizeof(char) + 1);
  198.             DecimalToBinary(k1, byte1);
  199.             flag = 0;
  200.             for (int i = 0; i < 4096; i++) {
  201.                 if (strcmp(byte12[i].symb_code, byte1) == 0) {
  202.                     flag = 1;
  203.                     byte12[i].count += 1;
  204.                 }
  205.             }
  206.             if (flag == 0) {
  207.                 strcpy(byte12[j].symb_code, byte1);
  208.                 j++;
  209.             }
  210.         }
  211.         for (int i = 0; i < j; i++) {
  212.             if (byte12[i].count == 0)
  213.                 byte12[i].count += 1;
  214.         }
  215.         for (int i = 0; i < j; i++) //в массив указателей заносим адреса записей
  216.             psym[i] = &byte12[i];
  217.         sort(byte12, j);
  218.         clear(byte12, j);
  219.         table *root = make_tree(psym, j);
  220.         make_code(root);
  221.         for (int i = 0; i < j; i++) {
  222.  
  223.             printf("%016s - %d   %s\n", byte12[i].symb_code, byte12[i].count, byte12[i].new_symb_code);
  224.         }
  225.         printf("количество символов: %d\n", text_lenght1);
  226.         count_comp(byte12, j, 12);
  227.  
  228.  
  229.         //записываю в структуру коды символов по 16 бит, обнуля счетчик повтора
  230.     } else if (input == 3) {
  231.         table byte16[65536];
  232.         for (int i = 0; i < 65536; i++) {
  233.             byte16[i].count = 0;
  234.         }
  235.         table *psym[65536];
  236.         int j = 0;
  237.         int flag = 0;
  238.         while (!feof(text)) {
  239.             int b1 = getc(text);
  240.             int b2 = getc(text);
  241.             //сдвигаю первый байт на 8 и логическим или добавляю второй байт
  242.             int k = ((b1 << 8) | (b2));
  243.             char *byte1 = calloc(16, sizeof(char) + 1);
  244.             DecimalToBinary(k, byte1);
  245.             flag = 0;
  246.             for (int i = 0; i < 65536; i++) {
  247.                 if (strcmp(byte16[i].symb_code, byte1) == 0) {
  248.                     flag = 1;
  249.                     byte16[i].count += 1;
  250.                 }
  251.             }
  252.             if (flag == 0) {
  253.                 strcpy(byte16[j].symb_code, byte1);
  254.                 j++;
  255.             }
  256.  
  257.         }
  258.         for (int i = 0; i < j; i++) {
  259.             if (byte16[i].count == 0)
  260.                 byte16[i].count += 1;
  261.         }
  262.  
  263.         for (int i = 0; i < j; i++) //в массив указателей заносим адреса записей
  264.             psym[i] = &byte16[i];
  265.         sort(byte16, j);
  266.         clear(byte16, j);
  267.         table *root = make_tree(psym, j);
  268.         make_code(root);
  269.         for (int i = 0; i < j; i++) {
  270.  
  271.             printf("%016s - %d   %s\n", byte16[i].symb_code, byte16[i].count, byte16[i].new_symb_code);
  272.         }
  273.         printf("количество символов: %d\n", text_lenght2);
  274.         count_comp(byte16, j, 16);
  275.  
  276.         //записываю в структуру коды символов по 20 бит, обнуля счетчик повтора
  277.     } else if (input == 4) {
  278.         table byte20[10485];
  279.         for (int i = 0; i < 10485; i++) {
  280.             byte20[i].count = 0;
  281.         }
  282.         table *psym[10485];
  283.         int j = 0;
  284.         int flag = 0;
  285.         while (!feof(text)) {
  286.             int b1 = getc(text);
  287.             int b2 = getc(text);
  288.             int b3 = getc(text);
  289.             int b4 = getc(text);
  290.             int b5 = getc(text);
  291.             // сдвигаю первый байт на 12 бит и второй байт на 4 бита  а третий на 4 бита и соездиняю их логическим или
  292.             int k = ((b1 << 12) | ((b2 << 4) | (b3 >> 4)));
  293.             //сдвигаю 4 байт на 8 бит а оставшуюся часть 3 байта сдвигаю на 16 бит и соединяю логическим или с 4 и 5 байтом
  294.             int k1 = ((b4 << 8) | (b5) | (b3 & 15) << 16);
  295.             char *byte1 = calloc(20, sizeof(char) + 1);
  296.             DecimalToBinary(k, byte1);
  297.             flag = 0;
  298.             for (int i = 0; i < 10485; i++) {
  299.                 if (strcmp(byte20[i].symb_code, byte1) == 0) {
  300.                     flag = 1;
  301.                     byte20[i].count += 1;
  302.                 }
  303.             }
  304.             if (flag == 0) {
  305.                 strcpy(byte20[j].symb_code, byte1);
  306.                 j++;
  307.             }
  308.             byte1 = calloc(20, sizeof(char) + 1);
  309.             DecimalToBinary(k1, byte1);
  310.             flag = 0;
  311.             for (int i = 0; i < 10485; i++) {
  312.                 if (strcmp(byte20[i].symb_code, byte1) == 0) {
  313.                     flag = 1;
  314.                     byte20[i].count += 1;
  315.                 }
  316.             }
  317.             if (flag == 0) {
  318.                 strcpy(byte20[j].symb_code, byte1);
  319.                 j++;
  320.             }
  321.         }
  322.  
  323.         for (int i = 0; i < j; i++) {
  324.             if (byte20[i].count == 0)
  325.                 byte20[i].count += 1;
  326.         }
  327.  
  328.         for (int i = 0; i < j; i++) //в массив указателей заносим адреса записей
  329.             psym[i] = &byte20[i];
  330.         sort(byte20, j);
  331.         clear(byte20, j);
  332.         table *root = make_tree(psym, j);
  333.         make_code(root);
  334.         for (int i = 0; i < j; i++) {
  335.  
  336.             printf("%024s - %d   %s\n", byte20[i].symb_code, byte20[i].count, byte20[i].new_symb_code);
  337.         }
  338.         printf("количество символов: %d\n", text_lenght3);
  339.         count_comp(byte20, j, 20);
  340.     }
  341.  
  342.     return 0;
  343. }
  344.  
Advertisement
Add Comment
Please, Sign In to add comment