Huffman编码/译码问题
2022/1/17 23:38:42
本文主要是介绍Huffman编码/译码问题,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
Huffman编码/译码
问题描述
利用哈夫曼编码进行信息通讯可以大大提高信道利用率,缩短信息传输时间,降低传输成本。但是,这要求在发送端通过一个编码系统对待传数据预先编码;在接收端将传来的数据进行译码(复原)。对于双工信道(即可以双向传输信息的信道),每端都需要一个完整的编/译码系统。试为这样的信息收发站写一个哈夫曼码的编译码系统。
基本要求
一个完整的系统应具有以下功能:
(1) I:初始化(Initialization)。从终端读入字符集大小n,及n个字符和n个权值,建立哈夫曼树,并将它存于文件hfmtree中。
(2) C:编码(Coding)。利用已建好的哈夫曼树(如不在内存,则从文件hfmtree中读 入),对文件tobetrans中的正文进行编码,然后将结果存入codefile中。
(3) D:译码(Decoding)。利用已建好的哈夫曼树将文件codefile中的代码进行译 码,结果存入文件textfile中。
(4) P:印代码文件(Print)。将文件codefile以紧凑格式显示在终端上,每行50个代 码。同时将此字符形式的编码文件写入文件codeprint中。
(5) T:印哈夫曼树(Tree print)。将已在内存中的哈夫曼树以直观的方式 树或凹入表行式)显示在终端上,同时将此字符形式的哈夫曼树写入文件treeprint中。
测试数据:
用下表中给出的字符集和频度的实际统计数据建立哈夫曼树,并实现以下报文的编码和译码: “THIS PROGRAM IS MY FAVORITE”.
实现提示
(1) 文件codefile的基类型可以设为子界型 bit=0…1。
(2) 用户界面可以设计为"菜单"方式: 显示上述功能符号,再加上"E",表示结束运行End,请用户键入一个选择功能符。此功能执行完毕后再显示此菜单,直至某次用户选择了"E"为止。
(3) 在程序的一次执行过程中,第一次执行I,D或C命令之后,哈符曼树已经在内存了,不必再读入。每次执行中不一定执行I命令,因为文件hfmtree可能早己建好。
#include <stdio.h> #include <stdbool.h> #include <stdlib.h> #include <string.h> typedef struct HT{ int val; char word; bool bitt[30]; struct HT *left, *right; }; struct HT *Huffman_Tree[30], *roott; bool Huff[30][30]; char Huffq[30][30]; int nn = 30, HuffLen[30]; void Build_Tree(int n, struct HT *root, int k) { struct HT *q = (struct HT*) malloc(sizeof(struct HT)); q->left = NULL; q->right = NULL; q->val = 0; if (Huffq[n][k] == '\0') { if (n == 26) { root->word = ' '; } else { root->word = n + 'A'; } } else if (Huffq[n][k] == '0') { if (root->left == NULL) { q->word = '*'; root -> left = q; Build_Tree(n, q, k + 1); } else { Build_Tree(n, root->left, k + 1); } } else if (Huffq[n][k] == '1') { if (root->right == NULL) { q->word = '*'; root -> right = q; Build_Tree(n, q, k + 1); } else { Build_Tree(n, root->right, k + 1); } } } void Readhfmtree() { char s[30]; FILE *fp = NULL; fp = fopen("../hfmtree.txt", "r"); if (fp == NULL) { printf("The document does not exist\n"); } int sum = 0; while(!feof(fp)) { memset(s, '\0', sizeof(s)); fgets(s, 30, fp); for (int i = 2; i < strlen(s); i++) { if (s[i] == '\n') { break; } Huffq[sum][i - 2] = s[i]; } sum++; } fclose(fp); roott = (struct HT*) malloc(sizeof(struct HT)); roott->left = NULL; roott->right = NULL; roott->word = '*'; roott->val = 0; for (int i = 0; i < 27; i++) { Build_Tree(i, roott, 0); } } void sortt(int n) { for (int i = 0; i < n - 1; i++) { for(int j = i + 1; j < n; j++) { if (Huffman_Tree[i]->val < Huffman_Tree[j]->val) { struct HT *temp = Huffman_Tree[i]; Huffman_Tree[i] = Huffman_Tree[j]; Huffman_Tree[j] = temp; } } } } void Build_Bitt(struct HT *root, int k) { if (root == NULL) { return; } if (root->word >= 'A' && root->word <= 'Z') { memcpy(Huff[root->word - 'A'], root->bitt, k + 1); HuffLen[root->word - 'A'] = k; } else if (root->word == ' ') { memcpy(Huff[26], root->bitt, k + 1); HuffLen[26] = k; } if (root -> left != NULL) { memcpy(root->left->bitt, root->bitt, k + 1); root->left->bitt[k + 1] = false; Build_Bitt(root->left, k + 1); } if (root -> right != NULL) { memcpy(root->right->bitt, root->bitt, k + 1); root->right->bitt[k + 1] = true; Build_Bitt(root->right, k + 1); } } void Initialization() { char ch; int q; getchar(); printf("input the letter and its val\n"); for (int i = 0; i < 27; ++i) { scanf("%c %d", &ch, &q); struct HT *ht = (struct HT*)malloc(sizeof(struct HT)); ht->word = ch; ht->val = q; ht->left = NULL; ht->right = NULL; memset(ht->bitt, false, sizeof(ht->bitt)); getchar(); if (ch == ' ') { Huffman_Tree[26] = ht; } else { Huffman_Tree[ch - 'A'] = ht; } } sortt(27); int m = 27; while(m != 1) { struct HT *ht = (struct HT *)malloc(sizeof(struct HT)); ht->left = Huffman_Tree[m - 2]; ht->right = Huffman_Tree[m - 1]; ht->word = '*'; ht->val = ht->left->val + ht->right->val; memset(ht->bitt, false, sizeof(ht->bitt)); Huffman_Tree[m - 2] = ht; sortt(m); m--; } Build_Bitt(Huffman_Tree[0], 0); FILE *fp = NULL; fp = fopen("../hfmtree.txt","w"); if (fp == NULL) { printf("Document Error"); } for (int i = 0; i < 27; i++) { char s[30]; memset(s, '\0', sizeof(s)); if (i == 27 - 1) { s[0] = ' '; } else { s[0] = 'A' + i; } s[1] = ' '; for (int j = 1; j <= HuffLen[i]; ++j) { if (Huff[i][j] == false) { s[j + 1] = '0'; } else { s[j + 1] = '1'; } } fprintf(fp, s); fprintf(fp, "\n"); } fclose(fp); } void Coding() { char s[300]; memset(s, '\0', sizeof(s)); gets(s); FILE *fp = NULL; fp = fopen("../codefile.txt","w"); if (fp == NULL) { printf("Document Error"); } for (int i = 0; i < strlen(s); i++) { if (s[i] >= 'A' && s[i] <= 'Z') { fprintf(fp, Huffq[s[i] - 'A']); } else if (s[i] == ' ') { fprintf(fp, Huffq[26]); } else { char ch[2]; ch[0] = s[i]; ch[1] = '\0'; fprintf(fp, ch); } } fprintf(fp, "\n"); fclose(fp); }; void Decoding() { char s1[3000], s2[3000]; FILE *fp1 = NULL, *fp2 = NULL; fp1 = fopen("../codefile.txt","r"); fp2 = fopen("../textfile.txt","w"); if (fp2 == NULL) { printf("Document Error"); } if (fp1 == NULL) { printf("Document Not exist"); } while (!feof(fp1)) { memset(s1, '\0', sizeof(s1)); memset(s2, '\0', sizeof(s2)); fgets(s1, 3000, fp1); struct HT *q = roott; int sum = 0; for (int i = 0; i < strlen(s1); ++i) { if (s1[i] == '0') { q = q->left; } else if (s1[i] == '1') { q = q->right; } else { s2[sum++] = s1[i]; } if (q->word != '*') { s2[sum++] = q->word; q = roott; } } fprintf(fp2, s2); fprintf(fp2, "\n"); } fclose(fp2); fclose(fp1); } void Print() { char s[1000]; FILE *fp = NULL; fp = fopen("../codefile.txt","r"); if (fp == NULL) { printf("Document Not exist"); } while(!feof(fp)) { memset(s, '\0', sizeof(s)); fgets(s, 1000, fp); for (int i = 0; i < strlen(s); ++i) { printf("%c", s[i]); if ((i + 1) % 50 == 0) { printf("\n"); } } } fclose(fp); } void Tree_Print() { FILE *fp; fp = fopen("../treeprint.txt","w"); if (fp == NULL) { printf("Document Error"); } int sum = 30; char s[50]; for (int i = 0; i < 27; ++i) { memset(s, '\0', sizeof(s)); if (i == 26) { s[0] = ' '; } else { s[0] = 'A' + i; } s[1] = ' '; for (int j = 0; j < sum - strlen(Huffq[i]) * 2; ++j) { s[j + 2] = '='; } fprintf(fp, s); fprintf(fp,"\n"); printf("%s\n",s); } fclose(fp); } int main() { char c; while (1) { printf(" 1.Initialization\n 2.Coding\n 3.Decoding\n 4.Print\n 5.Tree print\n"); printf("input the number of the instruction to use the instructions, or input e/E to exit\n"); scanf("%c",&c); if (c == 'E' || c == 'e') { break; } else { if (c == '1') { Initialization(); } else if (c == '2') { Readhfmtree(); getchar(); Coding(); } else if (c == '3') { Readhfmtree(); Decoding(); } else if (c == '4') { Print(); } else if (c == '5') { Readhfmtree(); Tree_Print(); } } } return 0; }
这篇关于Huffman编码/译码问题的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-26JAVA语音识别项目资料的收集与应用
- 2024-11-26Java语音识别项目资料:入门级教程与实战指南
- 2024-11-26SpringAI:Java 开发的智能新利器
- 2024-11-26Java云原生资料:新手入门教程与实战指南
- 2024-11-26JAVA云原生资料入门教程
- 2024-11-26Mybatis官方生成器资料详解与应用教程
- 2024-11-26Mybatis一级缓存资料详解与实战教程
- 2024-11-26Mybatis一级缓存资料详解:新手快速入门
- 2024-11-26SpringBoot3+JDK17搭建后端资料详尽教程
- 2024-11-26Springboot单体架构搭建资料:新手入门教程