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语言---数据结构实验---哈夫曼树及哈夫曼编码的算法实现---图的基本操作
C语言---数据结构实验---哈夫曼树及哈夫曼编码的算法实现---图的基本操作
|
存储 C语言
数据结构基础详解(C语言): 树与二叉树的应用_哈夫曼树与哈夫曼曼编码_并查集_二叉排序树_平衡二叉树
本文详细介绍了树与二叉树的应用,涵盖哈夫曼树与哈夫曼编码、并查集以及二叉排序树等内容。首先讲解了哈夫曼树的构造方法及其在数据压缩中的应用;接着介绍了并查集的基本概念、存储结构及优化方法;随后探讨了二叉排序树的定义、查找、插入和删除操作;最后阐述了平衡二叉树的概念及其在保证树平衡状态下的插入和删除操作。通过本文,读者可以全面了解树与二叉树在实际问题中的应用技巧和优化策略。
311 2
|
存储 程序员 C语言
揭秘C语言:这些核心知识你掌握了吗?一篇文章带你突破编程基础,开启高效编码之旅!
【8月更文挑战第22天】C语言作为编程基石,以简洁高效著称,历经数十年仍备受欢迎。本文通过梳理C语言的核心概念,帮助读者深入理解并提升技能。适合各水平读者。基础语法从`main`函数开始,如示例中的“Hello, World!”程序所示。C语言强调头文件包含与语句结尾的分号。变量和数据类型丰富多样,如`int`、`float`、`char`等,合理选择可优化内存使用和性能。指针用于间接访问内存,是C语言的关键特性。控制结构如循环和分支使程序逻辑更灵活。函数支持代码复用与模块化。深入学习还需掌握预处理指令、文件操作等高级特性。通过系统学习与实践,你将能更熟练地使用C语言,构建高效稳定的应用。
202 4
|
C语言
c语言数据结构-哈夫曼树
c语言数据结构-哈夫曼树
229 0
|
C语言
C语言《数据结构》——哈夫曼树
C语言《数据结构》——哈夫曼树
487 0
|
存储 安全 Java
【C语言安全编码之可重入函数】2、线程安全
【C语言安全编码之可重入函数】2、线程安全
470 0
【C语言安全编码之可重入函数】2、线程安全
|
人工智能 网络协议 Unix
C语言入门(九)——编码风格
C语言入门(九)——编码风格
|
算法 C语言
哈夫曼树的C语言详解
哈夫曼树的C语言详解
281 0
|
14天前
|
存储 C语言
`scanf`是C语言中用于按格式读取标准输入的函数
`scanf`是C语言中用于按格式读取标准输入的函数,通过格式字符串解析输入并存入指定变量。需注意输入格式严格匹配,并建议检查返回值以确保读取成功,提升程序健壮性。
476 0
|
3月前
|
安全 C语言
C语言中的字符、字符串及内存操作函数详细讲解
通过这些函数的正确使用,可以有效管理字符串和内存操作,它们是C语言编程中不可或缺的工具。
246 15