基于C++实现的赫夫曼编译码器开发

目录
一、实验目的及要求 0
(5)密码文件以文件的形式进行存放。 0
二、算法原理概述 1
(一)Huffman树 1
1.Huffman树简介 1
2.Huffman树的构造 1
(二)Huffman编码 2
1.Huffman编码简介(来源于百度百科) 2
2.Huffman编码的实现 2
(三)Huffman译码 3
1.Huffman译码简介 3
2.Huffman译码的实现 3
(四)huf文件编码算法 3
1.对二进制文件的写入 3
2.Huffman编码的实现 3
(五)huf文件译码算法 4
1.对二进制文件的读取 4
2.对Huffman编码的解压缩 4
三、软件开发环境及工具 5
四、实验内容 5
1、问题提出: 6
(2)发送的二进制编码尽可能地短。 6
2解决思路: 6
3、算法步骤: 6

  1. Status File_sourceload() 8
  2. LinkList p = L->next;	10
    
  3.    List_Destroy(L);	12
    

(7)核心代码块7://文件的解码操作 12
(8)核心代码块8: //比较输入文件和输出文件计算正确率 12
4、 结果分析: 13
5.不足之处分析: 16
五、实验总结 16
六、参考文献: 17
[2] C语言程序设计(第二版) 朱立剑主编 人民邮电出版社 17
43. ElemType elem; 18
54. L->next = nullptr; 19
61. LinkList p, s; 19
80. LinkList p; 19
84. L = p->next; 19
98. Status File_sourceload() 20
三、软件开发环境及工具
计算机版本: Windows 10 专业版(H20)
处理器: Intel® Core™ i7-10750H CPU @2.60GHz
显卡: NVIDIA GeForce GTX 1650ti
机带:RAM 16.0 GB
开发软件:
CLion (2021.3) 专业版
运行时版本: 11.0.13+7-b1751.19 amd64
VM: OpenJDK 64-Bit Server VM,JetBrains s.r.o.
编译运行(控制台):
Target: i686-w64-mingw32
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 10.2.0 (Rev6, Built by MSYS2 project)
GNU gdb (GDB) 9.2
部分代码基于C++14标准,C基于C11标准进行开发调试

四、实验内容
1、问题提出:
目前,进行快速远距离通信的主要手段仍然是报文,即将需传送的文字转换成由二进制的字符组成的字符串。在设计编码时需要遵守两个原则:
(1)发送方传输的二进制编码,到接收方解码后必须具有唯一性,即解码结果与发送方发送的完全一样;
(2)发送的二进制编码尽可能地短。
2解决思路:
通过设计哈夫曼编码/译码系统对文件进行处理,以达到快速传输和压缩存储的目的。
3、算法步骤:
①统计字符频率;
②创建Huffman树;
③求每个字符的Huffman码;
④对文件进行Huffman编码;
⑤根据编码生成huf文件;
⑥计算Huffman压缩率;
⑦根据编码翻译huf文件;
⑧对huf翻译文件进行解码;
⑨比较输入文件与输出文件,得到最终结构

//项目要求:
//(
//1)系统功能:从文件或键盘读入一串电文字符,实现赫夫曼编码和译码。
//
//2)密码文件以文件的形式进行存放。
//项目目的:
//
//1)考查二叉树存储表示及其基本操作实现。
//
//2)赫夫曼数的建立。
//
//3)赫夫曼树编码和译码算法。

#include 
#include 
#include //目录操作头
#include 
#include 
#include 
#include //暂停Sleep()
#include 

#define OK 1
#define ERROR 0

using namespace std;//使用标准命名空间

typedef int Status;

/**链表元素的定义*/
typedef struct
{
    int char_ASCII;
    int value;               //字符的出现频率或权值
    char *Huffmancode;       //Huffman编码所在数组的指针;
    int Huffmancode_bit = 0; //Huffmancode数组的长度。
} ElemType;

/**链表的定义*/
typedef struct Node
{
    ElemType elem;
    struct Node *next;
} LinkNode, *LinkList;

/**链表初始化*/
Status List_Init(LinkList &L)
{
    if (!(L = (LinkList) malloc(sizeof(LinkNode))))
    {
        exit(ERROR);
    }//内存分配失败
    L->next = nullptr;
    return OK;
}

/**链表插入*/
Status List_Insert(LinkList &L, int i, ElemType e)
{
    LinkList p, s;
    p = L;
    int j = 0;
    while (p && j < i - 1)
    {
        p = p->next;
        j++;
    }
    if (j > i - 1 || !p) return ERROR;
    s = (LinkList) malloc(sizeof(LinkNode));
    s->elem = e;
    s->next = p->next;
    p->next = s;
    return OK;
}

/**删除链表*/
Status List_Destroy(LinkList &L)
{
    LinkList p;
    while (L)
    {
        p = L;
        L = p->next;
        free(p);
    }
    return OK;
}

/**Huffman树的定义*/
typedef struct
{
    unsigned int value, ASCII_CODE;     //叶子结点的权值和所对应的字符的ASCII码
    unsigned int parent, lchid, rchild; //双亲节点和左右孩子节点
} HTNode, *HuffmanTree;

/**读取源文件信息,统计字符出现频率*/
Status File_sourceload()
{
    FILE *fp1 = fopen("testText.txt", "r");
    int char_num[256] = {0};  //根据ASCII表,有256个字符
    int text_length = 0, char_number = 0;
    int i, l = 0;
    char c;

    //初始化文件,若不存在则退出
    if (fp1 == nullptr)
    {
        printf("读取文件失败或文件不存在!请重试!\n");
        return (ERROR);
    }
    //统计字符频率及字符串长度
    while ((c = fgetc(fp1)) != EOF)
    {
        char_num[c]++;
        text_length++;
    }
    //统计字符串中有多少种不同字符
    for (i = 0; i < 256; i++)
    {
        if (char_num[i] != 0)
        {
            char_number++;
        }
    }
    fclose(fp1);

    //结果写入:字符串长度、出现的字符种类
    _mkdir("huffman_temp");
    FILE *fp2 = fopen("huffman_temp\\char_frequency.txt", "w+");
    fprintf(fp2, "%d\t%d", text_length, char_number);
    for (i = 0; i < 256; i++)
    {
        if (char_num[i] != 0)
        {
            fprintf(fp2, "\n%d %d", i, char_num[i]);
        }
    }
    //写入文本注释
    fprintf(fp2, "\n\n****注:该文件用来存储源文件中的字符数量、字符种类个数、每个字符对应的ASCII码及他们的出现频率!****\n");
    char fileadress[100];
    _getcwd(fileadress, 100);
    printf("文本字符统计完毕!\n信息保存在%s\\huffman_temp\\char_frequency.txt\n\n", fileadress);
    fclose(fp2);

    //结果输出
    printf("文本长度:%d    字符种类:%d\n", text_length, char_number);
    printf("按照ASCII码排列,字符出现频率如下:\n");
    for (i = 0; i < 256; i++)
    {
        if (char_num[i] != 0)
        {
            if (i == 32) { printf("空格:%d\n", char_num[i]); }
            else if (i == 13) { printf("回车:%d\n", char_num[i]); }
            else if (i == 10) { printf("换行:%d\n", char_num[i]); }
            else { printf("%c:%d\t\t", i, char_num[i]); }
            l++;
            if (l % 5 == 0) { printf("\n"); }
        }
    }
    printf("\n");
    return OK;
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
基于C++实现的赫夫曼编译码器开发_第1张图片
在这里插入图片描述
基于C++实现的赫夫曼编译码器开发_第2张图片
在这里插入图片描述
基于C++实现的赫夫曼编译码器开发_第3张图片
基于C++实现的赫夫曼编译码器开发_第4张图片
基于C++实现的赫夫曼编译码器开发_第5张图片
基于C++实现的赫夫曼编译码器开发_第6张图片
基于C++实现的赫夫曼编译码器开发_第7张图片
基于C++实现的赫夫曼编译码器开发_第8张图片
基于C++实现的赫夫曼编译码器开发_第9张图片
基于C++实现的赫夫曼编译码器开发_第10张图片

你可能感兴趣的:(c++,赫夫曼,编译码器,源码,课程设计)