哈弗曼编码
来源:互联网 发布:北京的设计公司知乎 编辑:程序博客网 时间:2024/06/08 19:07
#include<cstdio>#include<cstring>#include<cstdlib>#include<iostream>using namespace std;typedef struct{ char ch; int weight; int lchild,rchild,parents;}HNode,*HLink;typedef char **Haffmancode;char b[1000];int kinds;int deciph = 1;HLink Hc;Haffmancode Hccode;void coding();void decipher();void minterface();void showthecode();Haffmancode Haffmanbuilt(HLink &Hc);staticint a[256];void clrscr(){ system("cls");}void Dataread(char *mingwen){ char c; int k = 0, i, tim = 1; getchar(); while((c = getchar()) != '#') { if(tim && deciph) for(tim = 0, i = 0; i < 256; i++) a[i] = 0; mingwen[k++] = c; if(deciph) a[c]++; } if(deciph){ Hccode = Haffmanbuilt(Hc); showthecode(); } mingwen[k] = '\0';}Haffmancode Haffmanbuilt(HLink &Hc){ int i, n = 0, m, t = 0, start; Haffmancode Hccode; kinds = 0; for(i = 0; i < 256; i++) if(a[i]) kinds++; start = kinds + 1; m = 2 * kinds - 1; Hc = (HLink)malloc((m+1) * sizeof(HNode)); for(i = 0; i < 256; i++) { if(a[i]){ b[++t] = i; Hc[t].ch = i; Hc[t].weight = a[i]; Hc[t].lchild = Hc[t].rchild = Hc[t].parents = 0; } } b[++t] = '\0'; for(i = kinds + 1; i <= m; i++){ Hc[i].ch = '#'; Hc[i].lchild = Hc[i].rchild = Hc[i].parents = 0; } while(start <= m){ int min1 = INT_MAX,min2 = INT_MAX,min1num,min2num; for(i = 1; i < start; i++){ if(!Hc[i].parents){ if(Hc[i].weight < min1){ min2 = min1; min2num = min1num; min1 = Hc[i].weight; min1num = i; } else if(Hc[i].weight < min2) { min2 = Hc[i].weight; min2num = i; } } } Hc[start].weight = Hc[min1num].weight + Hc[min2num].weight; Hc[start].lchild = min2num; Hc[start].rchild = min1num; Hc[min1num].parents=Hc[min2num].parents=start; start++; } Hccode = (Haffmancode)malloc((kinds+1) * sizeof(char *)); for(i = 1; i <= kinds; i++) { char *cd; int p, c; cd = (char *)malloc(kinds * sizeof(char)); start = kinds - 1; cd[start] = '\0'; c = i; while(p = Hc[c].parents){ if(c == Hc[p].lchild) cd[--start] = '0'; else cd[--start] = '1'; c = p; } Hccode[i] = (char *)malloc((kinds - start) * sizeof(char)); strcpy(Hccode[i],&cd[start]); } return Hccode;}void replace(char *mingwen,char *secreat){ int i = 2 * kinds - 1, j = 0, start = 0, k = 0; while(secreat[j] != '\0'){ if(secreat[j] == '1') i = Hc[i].rchild; else i = Hc[i].lchild; if(Hc[i].lchild == 0 && Hc[i].rchild == 0){ mingwen[k++] = Hc[i].ch; i = 2 * kinds - 1; } j++; } if(i != 2 * kinds - 1) mingwen[k++] = '#'; mingwen[k] = '\0';}void translate(char *secreat,char *mingwen){ int i, j, start = 0, k = 0; while(mingwen[start] != '\0'){ for(i = 1; i <= kinds; i++){ if(b[i] != mingwen[start]) continue; else{ for(j = 0; Hccode[i][j] != '\0'; j++){ secreat[k++] = Hccode[i][j]; } start++; break; } } if(i > kinds){ secreat[k++] = '#'; start++; } } secreat[k] = '\0';}void minterface(){ clrscr(); printf("\t\t哈夫曼编码译码\n---------编码-----输入1\n---------译码-----输入2\n---------退出-----输入3\n"); printf("\t\tshow you command:"); int r; scanf("%d",&r); switch(r){ case 1: coding(); break; case 2: decipher(); break; case 3: return; break; }}void coding(){ char txt[1000],code[10000],txt2[1000]; int r; clrscr(); printf("请输入你想编码的文段(以'#'作为结束标志):\n"); deciph = 1; Dataread(txt); translate(code,txt); printf("原文的哈夫曼编码为:"); puts(code); printf("\n\t\t\t 返回----------输入0:\n\t\t\t继续编一下一段----------输入1:\n\t\t\t验证编码正确性----------输入3:"); printf("\n\t\tshow you command:"); scanf("%d",&r); if(r==1) coding(); else if(r == 0) minterface(); else if(r == 3){ replace(txt2,code); printf("破译上段密码如下:\n"); puts(txt2); printf("\n\n\n\t\t\t------回主界面----------输入0:\n\t\t\t继续编一下一段----------输入1:"); printf("\n\t\tshow you command:"); scanf("%d",&r); if(r) coding(); else minterface(); }}void decipher(){ char txt[1000],code[10000]; int r; clrscr(); showthecode(); loop: printf("\n请输入你想破译的编码(以'#'作为结束标志):\n"); deciph = 0; Dataread(code); replace(txt,code); printf("这段哈夫曼编码的原文为:"); puts(txt); printf("\n\t\t\t 返回----------输入0:\n\t\t\t继续编一下一段----------输入1:\n\t\t\t 显示编码表----------输入2:"); printf("\n\t\tshow you command:"); scanf("%d",&r); if(r){ if(r==2) showthecode(); goto loop; } else minterface();}void showthecode(){ int i; printf("哈夫曼编码如下: \n"); for(i = 1; b[i] != '\0'; i++){ printf("%9s\t",Hccode[i]); if(b[i] == '\n') printf("换行符\n"); else if(b[i] == ' ') printf("空格\n"); else printf("%c\n",b[i]); }}int main(){ minterface(); return 0;}
0 0
- 香农编码、费诺编码、哈弗曼编码
- 哈弗曼编码
- 哈弗曼编码
- 哈弗曼编码
- 哈弗曼编码
- 哈弗曼编码
- 哈弗曼编码
- 哈弗曼编码
- 哈弗曼编码
- 哈弗曼编码
- 哈弗曼编码
- 哈弗曼编码
- 哈弗曼编码
- 哈弗曼编码
- 哈弗曼编码
- 哈弗曼编码
- 哈弗曼编码
- 哈弗曼编码(C++)
- jquery中prop()方法和attr()方法的区别
- Atom输入中文显示问号问题
- SCI论文写作全攻略
- [BZOJ2509][主席树]送分题
- ViewPager的一个应用,用fragment来当页面,可以左右滑动,上面有一条线,来分隔
- 哈弗曼编码
- 游艇出租站最少费用,动态规划算法!
- linux根据uid反查用户名
- 随笔之java面试
- 郝斌的C语言基础 170 补码 下
- jsp实现分页显示信息(数据库、EL表达式、连接池)
- 对javascript的Array中转换方法、栈和队列的理解
- Apache Curator简单使用(二)
- JavaScript 声明全局变量的三种方式详解