哈夫曼算法编码26字母程序实现C++
一、编程目的
(1)学习和理解树和二叉树的概念、特点和相关知识,理解和掌握二叉树的遍历操作的原理和方法;掌握二叉树的常用存储结构以及C++类的实现方法。
(2)学习最优二叉树的概念,理解和掌握哈夫曼算法的原理,掌握基于哈夫曼算法构造最优二叉树的方法;学习和掌握基于最优二叉树的哈夫曼编码方法。
(3)学会通过分析应用需求,结合理论知识来设计合理的数据结构与有效的求解算法;能够通过查找和学习技术资料、文档来掌握需用到的编程知识、技术;能够综合运用所学知识,利用开发环境提供的调试工具对程序进行调试,完成程序的开发、测试和完善。
二、26字母频率表
英文字母字符集及使用频率
字母 |
英语中出现的频率 |
字母 |
英语中出现的频率 |
字母 |
英语中出现的频率 |
字母 |
英语中出现的频率 |
a |
8.167% |
h |
6.094% |
o |
7.507% |
u |
2.758% |
b |
1.492% |
i |
6.966% |
p |
1.929% |
v |
0.978% |
c |
2.782% |
j |
0.153% |
q |
0.095% |
w |
2.360% |
d |
4.253% |
k |
0.772% |
r |
5.987% |
x |
0.150% |
e |
12.702% |
l |
4.025% |
s |
6.327% |
y |
1.974% |
f |
2.228% |
m |
2.406% |
t |
9.056% |
z |
0.074% |
g |
2.015% |
n |
6.749% |
三、代码实现
#include <iostream>
#include<iomanip>
#include<string.h>
using namespace std;
struct huff
{double weight;int parent, lch, rch;char cha;
};
struct code
{char cd[25];int start;
};
void input(huff hufftree[],char alpha[],double weight[])//初始化哈夫曼树,权值先全部赋0,再将频率录入
{for (int i = 0;i < 51;i++)hufftree[i].cha = '_';for (int i = 0;i < 26;i++)hufftree[i].cha= alpha[i];for (int i = 0;i < 51;i++)hufftree[i].weight = 0;for (int i = 0;i < 26;i++)hufftree[i].weight = weight[i];for (int i = 0;i < 51;i++){hufftree[i].parent = -1;hufftree[i].lch = -1;hufftree[i].rch = -1;}
}
void buildtree(huff hufftree[])
{int i, k, lnode, rnode;double mina, minb;for (i = 26;i < 51;i++)//从第一个结点开始,确定其孩子结点{mina = minb = 100;lnode = rnode = 0;//100和0只是初始化值,无特殊含义,取100是确保高于任意字母的频率,因为所有字母的频率和是100for (k = 0;k < 51&&hufftree[k].weight!=0;k++)//每一次遍历整个hufftree,将已经找到双亲结点的和尚未被使用的结点剔除,比较剩余结点{if (hufftree[k].parent == -1)//没找到双亲结点{if (hufftree[k].weight < mina)//每一轮后mina都会变为100,此时基本第一个进来的k就会执行这个if语句{minb = mina;//如果后续有更小的权,原先在mina的数据便会被移动到minb,暂时变为第二小rnode = lnode;mina = hufftree[k].weight;lnode = k;}else if (hufftree[k].weight < minb)//看看新的权值会不会替代成为第二小{minb = hufftree[k].weight;rnode = k;}//遍历整个hufftree后,此时mina和minb上都已经确定好这一轮的最小和次小,准备赋值给这一轮对应的未使用结点}}hufftree[lnode].parent = i;//确定双亲hufftree[rnode].parent = i;hufftree[i].weight = hufftree[lnode].weight + hufftree[rnode].weight;//确定未使用结点的权hufftree[i].lch = lnode;//确定未使用结点的孩子hufftree[i].rch = rnode;}//循环直到按照哈夫曼算法确定每个结点的值,构造完成}
void createcode(huff hufftree[],code alphac[])
{int i, f, c;code hc{};for(i=0;i<26;i++)//26次循环,确定26个字母{hc.start = 26;c = i;f = hufftree[i].parent;while (f != -1){if (hufftree[f].lch == c)hc.cd[hc.start--] = '0';else hc.cd[hc.start--] = '1';c = f;f = hufftree[f].parent;//向上再找一级,逆向从后向前储存}hc.start++;//读取时有用,确定长度alphac[i] = hc;//储存}
}
void display(code alphac[],huff hufftree[])
{int i, j;cout << "********* 欢迎使用哈夫曼编码程序 *************" << endl;cout << "********* 26字母表字符集对应哈夫曼编码如下: *************" << endl;for(i=0;i<26;i++){cout << hufftree[i].cha << " ";for (j = alphac[i].start;j <= 26;j++)cout << alphac[i].cd[j];//正向读取cout << endl;}cout << "************* 请输入接下来的操作: *************" << endl;cout << "************ 1.将单词翻译为哈夫曼编码 ********************" << endl;cout << "************ 2.将哈夫曼编码翻译为单词 ********************" << endl;cout << "请选择:" << endl;
}
void fromwordstohuff(code alphac[], huff hufftree[])
{int eye = 0;cout << "请输入你想编译的单词:" << endl;char input[1000];cin >> input;cout << input << "的编码为:" ;for (int i = 0;input[i] != '\0';i++){char temp = input[i];for (int k = 0;k < 26;k++){if (temp == hufftree[k].cha){for (int j = alphac[k].start;j <= 26;j++)cout << alphac[k].cd[j];//正向读取eye++;}}}if (eye < strlen(input)){cout << endl;cout << "您输入的单词中或含非法字符,已过滤,请您留意!" << endl;//鲁棒性容错}cout << endl;
}
void fromhufftowords(code alphac[], huff hufftree[],char code[])
{cout<< "该编码对应单词为:" ;int i, j;struct array { char storecode[10]; };array array1[26];for (i = 0;i < 26;i++){int q = 0;for ( j = alphac[i].start;j <= 26;j++){array1[i].storecode[q] = alphac[i].cd[j];q++;}array1[i].storecode[q] = '\0';//cout << array1[i].storecode << endl;(调试用)}int tt=0;//用于暂存i值char codecmp[1000];//构造用于比较的字符串int z;int w = 0;for (int i = 0;code[i] != '\0';) {int key=1;//用于判断是否跳出for循环//cout << w;w++;system("pause");(调试用)tt = i;for (z = 0;code[i] != '\0';z++){codecmp[z] = code[i];i++;}//完成拷贝codecmp[z++] = '\0';//加入截止符号i = tt;int len=0;int k = 0;for (;k < 26&&key==1;k++){ int d;for (d = 0; codecmp[d] != '\0';) { if (codecmp[d] == array1[k].storecode[d]){d++;if (array1[k].storecode[d] == '\0')//判断哈夫曼代码是否和字符集有相同的段落{cout << hufftree[k].cha;//如果有,输出该字符key = 0;//调整key,使得对于该字符的循环停止,重新从k=0开始,避免k继续往下加len = strlen(array1[k].storecode);}}else break;}}if (k == 26 && key == 1) {cout << "<——本条提示前为成功编译的字母,但此后存在哈夫曼码输入错误,请检查后重新输入" << endl;break;}i = i + len;key = 1;//重调key值是下一次正常进入循环}}
int main()
{int w; int t;char alpha[26] = { 'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z' };double weight[26] = { 8.167,1.492, 2.782,4.253,12.702,2.228,2.015,6.094,6.966,0.153,0.772,4.025,2.406,6.749,7.507,1.929,0.095,5.987,6.327,9.056,2.758,0.978,2.360,0.150,1.974,0.074 };huff hufftree[51];code alphac[26];input(hufftree, alpha, weight);buildtree(hufftree);createcode(hufftree, alphac);display(alphac, hufftree);//字母表、权值表、哈夫曼树和储存哈夫曼码的结构数组的建立while(1){ cin >> t;w = t;int guard = 0;switch(w){case 1: fromwordstohuff(alphac, hufftree);break;case 2: cout << "请输入哈夫曼码:" << endl;char code[1000];cin >> code;for (int check = 0;code[check] != '\0';check++){if (code[check] != '0' && code[check] != '1'){cout << "请输入二进制数字,请重试" << endl;guard = 1;break;}}if (guard == 1) { break; }fromhufftowords(alphac, hufftree,code);cout << endl;break;case 3: exit(1);default: cout << "请输入一个合理的选项" << endl;}cout << endl;cout << "************* 请输入接下来的操作: *************" << endl;cout << "************ 1.将单词翻译为哈夫曼编码 ********************" << endl;cout << "************ 2.将哈夫曼编码翻译为单词 ********************" << endl;cout << "************ 3.退出程序 ********************" << endl;cout << "请选择:" << endl;}}
四、运行结果
1、初始化
2、将单词编码为哈夫曼编码
3、将哈夫曼码编译为单词
五、结语
源代码很少调用函数,编程习惯也很糟糕,因为笔者对c++已经非常生疏,但觉得这个功能很有意思,所以还是磕磕绊绊写出来了一堆非常低效低级的代码,有的地方甚至非常冗余,源代码看着乐就好啦!
笔者过于小白,如果觉得有任何错漏和不足,恳请批评指正笔者,笔者感激不尽!
哈夫曼算法编码26字母程序实现C++相关推荐
- 哈夫曼算法证明+哈夫曼编码译码程序实现
哈夫曼算法证明 哈夫曼算法是一种贪心算法,我们考虑证明其最优子结构和贪心选择性质: 最优子结构:假设一个树是哈夫曼树,则以其任意节点为根节点的最大子树也是哈夫曼树. 证明:子树的根节点的值是其所有叶子 ...
- RLE算法机制、缺点及哈夫曼算法和莫尔斯编码
CSDN话题挑战赛第2期 参赛话题:学习笔记 目录 一.RLE算法机制 二.RLE算法的缺点 三.哈夫曼算法和莫尔斯编码 一.RLE算法机制 对 AAAAAABBCDDEEEEEF 这17个半角字符的 ...
- 赫夫曼树编码的算法及应用习题--数据结构
赫夫曼树编码的算法及应用习题 1.构造赫夫曼树的方法 1.根据给定的n个权值{w1,w2,---wn},构成n棵二叉树的集合F={T1,T2...,Tn},其中每棵二叉树中只有一个带权为Wi的根结点, ...
- 霍夫曼算法_霍夫曼编码算法
霍夫曼算法 In this tutorial, we'll be discussing and implementing the Huffman Coding Algorithm in Java. 在 ...
- 数据结构哈夫曼树实现26个英文字符的编码和译码
数据结构哈夫曼树实现26英文字符的编码和译码 那么首先什么是哈夫曼树?(知道的略过,直奔下面代码就好!) 在计算机数据处理中,霍夫曼编码使用变长编码表对源符号(如文件中的一个字母)进行编码,其中变长编 ...
- 哈夫曼字符串编码c语言实现,基于哈夫曼(haffuman)算法的文件压缩的实现(C语言)(原创)...
本文首先简要阐述哈夫曼算法的基本思想,然后介绍了使用哈夫曼算法进行文件压缩和解压缩的 处理步骤,最后给出了C语言实现的文件压缩和解压缩的源代码. 哈夫曼算法的主要思想是: ①首先遍历要处理的字符串,得 ...
- java哈夫曼树编码_哈夫曼树的编码实验
Java哈夫曼编码实验--哈夫曼树的建立,编码与解码 建树,造树,编码,解码 一.哈夫曼树编码介绍 1.哈夫曼树: (1)定义:假设有n个权值{w1, w2, ..., wn},试构造一棵含有n个叶子 ...
- 利用C++实现哈夫曼算法
我想每个计算机专业的学生或多或少都接触过哈夫曼编码,数据结构中的老问题了.大体就是给出一些字符,和这些字符的出现频率,让你为这些字符设计一个二进制编码,要求频率最高的字符的编码最短.解决的方法是构造一 ...
- 基于哈夫曼算法的文件压缩软件
数据结构课设(一) 作业要求 1.设计并实现一个使用哈夫曼算法对文件进行压缩的工具软件. 2.通过命令行参数指定操作模式(压缩/解压).源文件名.目标文件名. 3.压缩操作将源文件按字节读入并统计字节 ...
最新文章
- 虚拟机安装CentOS以及SecureCRT设置【完美无错版】
- DVWA安装——一个菜鸟的入门教程
- 【设计思想解读开源框架】java如何发送post请求
- 替换ExpandableListView右边箭头Group Indicator(小图标)
- css不换行属性_那些不常见,但却非常实用的css属性(整理不易)
- java http 状态_Java HTTP连接似乎保持打开状态
- boost::callable_traits的is_rvalue_reference_member的测试程序
- 基本概念—回归、分类、聚类
- oracle实现主键自动增长
- Sass笔记(CSS 的预编译语言)
- html地址--待更新
- 来看看 ETL 和数仓建模的设计思路!
- IOS视频播放器的使用(MPMoviePlayerController)
- 趣挨踢 | 只有挨踢人才能读懂的西游记
- C语言实现埃拉托色尼筛选法(剔除数组中的非质数)
- SEO人员快速提升关键词优化排名的方法
- java中方法的细分(普通方法,静态方法,构造方法)
- 5G基带芯片之战现状:一二三分别对应联发科华为高通
- 图算法入门4:活动网络-AOE网络和关键路径(critical path)
- GB28181-2016 协议(一)
热门文章
- xpspeak安装教程_查漏补缺:教你正确操作 XPS 分峰软件 XPSPEAK
- java 下载excel问题
- 微信小程序运动步数java_微信小程序实现运动步数排行(可删除)
- php搜索表格,table表格内对某列内容进行搜索筛选步骤详解
- ZZULIOJ.1108: 打印数字图形(函数专题)
- 谷歌浏览器切换黑色背景
- springboot junit测试时环境变量问题 idea
- 实验吧-让我进去【salt加密 哈希长度拓展攻击】
- 巨巨的磁盘(线段树)
- 编程网校课程python_如何看待风变编程的 Python 网课?