IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C语言实现哈夫曼树的译码以及编码 -> 正文阅读

[C++知识库]C语言实现哈夫曼树的译码以及编码

先附上代码效果图:
在这里插入图片描述
哈夫曼树编码讲解

前言:

先来吐个槽,相对于编码,解码应该是更加烧脑的一个过程,在不使用string类型,纯c语言的方法下,解码效率本身就低,还需要用到大量的for循环去得到编码是真的心累,就一个解码花了我两个小时,晕倒,但是最后解码成功是真的让人喜悦,不多bb,开始教程。
首先如果想要理解接下来的代码,那么先看一眼我之前的哈夫曼编码的代码,因为我是基于编码上修改的。

密文输入:

密文的输入很简单。直接贴代码,相信大家都能看得懂
可能比较难以理解的就是if里面for循环的部分,其实意思也就是先判断当前是哪一个字符,得到当前字符之后去得到这个字符对应的编码,比如a字符对应的编码是110,那么就通过for循环把1,1,0这三个字符依次循环复制到bcode这个存放密文的数组,最后最后一定要记得在密文的最后补上一个’\0’哦!!!

//输入ABCDABCD得出对应的编码 编码已知 
void Code(char**arr,int num)
{
	int length = 0; char code[100]; char bcode[300];
	cout << "输入你明文(明文应该只包含你之前输入的字符)" << endl;
	cin >> code; 
	for (int i = 0; code[i] != '\0'; i++)//对每一个字符进行编码操作
	{
		for (int j = 0; j < num; j++)//对当前字符进行判断,判断当前字符是哪一个编码
		{
			if (code[i] == arr[j][0])//如果是当前编码 那就取出对应的编码然后放入编码数组
			{
				for (int h = 1; arr[j][h] != '\0'; h++)//编码数组的结尾是结束符
				{
					bcode[length++] = arr[j][h];//将密文数组赋值编码
				}
			}
		}
	}
	bcode[length] = '\0';		//密文结尾放上结束标识符
	cout << "密文是:";
	for(int i=0;bcode[i]!='\0';i++)
		cout << bcode[i];
	cout << endl;
	Decode(arr, bcode, num); //调用解码函数
}

解码:

相对于简单的密文输入,解码的过程是真的烧脑,半个小时搞出思路,一个小时实现,半个小时debug,哭T-T。
那么接下来附上密文解密代码。
大致思路我用一张图来给大家呈现。
在这里插入图片描述
首先由于哈夫曼是非前缀码,所以我完全不需要担心误识别的情况,那么我就可以一个字符一个字符的与每个字符(假设为a)的编码去进行比对,比如我的密文第一位是1,那么我就可以与a的编码110去比对,发现不对,就退出一个循环,然后把b的编码放入数组,在进行一次比对也没有成功,循环往复,发现1不与任何字符能成功比对,那么我就在增加一个密文位,我用密文的前两个位与abcd四个字符的编码去比对,还是没有比对成功,那么我取到第三个密文位110的时候,我可以成功与a字符比对,那么我就输出a,循环往复,直到所有密文位都被我访问到,遇到了密文末尾的’\0’之后我就停止。
我创建了cmp和arrcmp两个数组,cmp用于存放当前的密文位(1,2,3…位),cmp用于存放字符abcd对应的编码,然后通过strcmp进行比较,比较成功就输出对应的字符,失败就继续for循环遍历下一个字符对应的编码。最后,解码成功


//已知字符对应的编码 已知密文 已知字符个数,字符个数-1可以得到最长的字符对应的编码
//strcmp函数可以用来比较两个字符串是否相同,我先取出num-1个字符串,然后逐一比较编码
//如果相同那么下标+num-1,不同则num-2,比较是否相同,循环往复
/*
需要引用#include <string.h>
比较字符串s1和s2: int strcmp(const char *s1, const char *s2);
比较字符串s1和s2前n个字符: int strncmp(const char *s1, const char *s2, size_t n);
如果两个字符一样大,返回值为 0, 如果s1>s2,则返回正值, 如果s1<s2,则返回负值
	int i = 0;
	char a[10] ;
	for (i = 0; i < 3; i++)
		cin >> a[i];
	a[i] = '\0';
	char b[10] = "asd";
	cout << strcmp(a, b);  返回0 说明可以使用这种方法,截取一部分的字符然后比较
	可以先取长度为1,也就是只取密文中的1个字符,然后用这个字符去遍历二维编码字符
	如果相同就输出对应的数据,然后数组后移去得到下一个,如果遍历完一次没有一样的,
	那么就增加这个数组中的数据,从密文中多取1一个数据,循环往复
*/
//解码函数 通过传递密文进去,解密
void Decode(char**arr,char*bcode,int num)
{
	int i; int j;
	int np = 0;//记录当前位置
	int flag = 0; //标志位 判断是否成功解码了一个字符
	int len = 1;//当前数据个数 初始为一个字符
	char cmp[10];//比较数组,用于比较编码是否一样
	char arrcmp[10];//二维数组中的编码
	cout << "收到的密文是:" << bcode << endl;
	while (bcode[np]!='\0')
	{
		for (len=1; flag != 1&&len<= num - 1; len++)
		{
			cmp[len - 1] = bcode[np];
			np++;
			cmp[len] = '\0';
			for (i = 0; i < num; i++)//二维数组中每一个行的遍历
			{
				for (j = 1; arr[i][j]!='\0'; j++)//二维数组中编码的遍历从1开始才是编码
				{
					arrcmp[j - 1] = arr[i][j]; //这个for用于先获取当前字符对应的编码
				}
				arrcmp[j - 1] = '\0'; //结束封顶 获取编码后下一步比较
				if (!strcmp(cmp, arrcmp))//两个数组内容一样
				{
					cout << arr[i][0];
					flag = 1;
				}
			}
		}
		flag = 0;
	}
}

代码下载:

由于这个代码可以直接通过拼接到上一篇文章中,所以我就不贴源代码了,如果真的懒得自己复制的话就下载把。
完整代码

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-11-30 15:24:34  更:2021-11-30 15:25:22 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 9:46:26-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码