主要目的是从文件中读取文本,经过哈夫曼算法编码成为01字符串,之后再将字符串解码。

强调的是不限制文章的大小,理论上【注】可以将一篇非常大的英文文章进行编码解码(当时做设计的时候从百度的一部分例子都是用的数组,限制文章的字数,所以我有了这个想法),同样也可以对较小的文章进行编码解码,而且不占用多余的空间。

(【注】:这里的理论上是指程序运行后文章内容不可变,且硬件支持)

先贴出要求:

哈夫曼编码的一个实例应用,实现英文字符的编码与解码。即针对一篇不少于100个单词的英文文章,统计文章中每个字符的出现概率(包括标点符号,区分大小写),根据分析结果对文章中每一个字符进行哈夫曼编码,并将编码原则存储于一个独立的文本文件中。然后,根据这个编码原则,将英文文章转换为01串存储于另一个文本文件中。最后,编写一个解码程序,还原文本文件中的01串为原英文文章。

应用哈夫曼算法实现如下基本功能:计算英文文章中每个字符的出现概率;计算英文文章中出现字符的哈夫曼编码;存储编码原则于txt文件中;英文文章转换为01串并存储;对01串进行解码转换为原英文文章。

要求系统运行正常、功能完整;数据结构使用得当,算法有较高的效率;代码规范、可读性高,结构清晰;具备一定的健壮性、可靠性和可维护性。

程序中部分算法和代码直接引用自《严蔚敏,吴伟民.数据结构(C语言版).北京:清华大学出版社,2011》。

程序中用的指针动态申请内存空间,储存要编码的英文文章,哈夫曼树等;用二级指针储存编码后的01字符串

下面直接上代码

huffman.h

#include <stdio.h>
#include <stdlib.h>
#include <string>
#define ASCIISize 127//储存哈夫曼树
typedef struct HTNode{int flag;         //叶子节点的标志位,0 代表不是叶子节点,1 代表是叶子节点 int parent;       //当前节点的父节点 int leftChild;       //当前节点的左子 int rightChild;       //当前节点的右子 int weight;       //当前节点的权值 char ch;      //当前节点代表的字母
}*HuffmansTree; 
//储存哈夫曼编码
typedef char * *HuffmanCode;//储存读取的文件
char *FileArray;//储存读取的文件的数组长度
int FileArraySize = 200;//储存每个ASCII码相应的权值
int weight[ASCIISize];//储存哈夫曼树
HuffmansTree HT;//储存哈夫曼编码
HuffmanCode HC;//储存文章的哈夫曼编码
char **FileCode;//储存文章的哈夫曼编码
int FileCodeSize = 20;//储存解码后的文件
char *_FileArray_;//储存解码后的文件的数组长度
int _FileArraySize_ = 200;//在HT[1..i-1]中选择两个parent为0且weight最小的,序号为s1,s2
void _Select(HuffmansTree HT, int i, int& s1, int& s2);//读取文件,并将文件中内容存入FileArray数组中
void ReadFile(char path[], char way[], char* &FileArray, int &FileArraySize);//求每个ASCII码对应字符的权值,并将权值存入weigh数组中
void Weight(char* FileArray, int weight[ASCIISize]);//根据每个字母的权值,创建哈夫曼树,求出哈夫曼编码
void CreateHaffTree(int weight[ASCIISize], HuffmansTree &HT, HuffmanCode &HC);

huffman.cpp

#include "huffman.h"
//在HT[1..i]中选择两个parent为0且weight最小的,序号为s1,s2
void _Select(HuffmansTree HT, int i, int& s1, int& s2){int j;int w1, w2, s;//选出最小 s1for (j = 1; j <= i; j++)if (HT[j].parent == 0) break;s1 = j;w1 = HT[j].weight;for (j++; j <= i; j++)if (HT[j].parent == 0 && HT[j].weight < w1)s1 = j, w1 = HT[j].weight;//选出次小 s2for (j = 1; j <= i; j++)if (HT[j].parent == 0 && j != s1) break;s2 = j;w2 = HT[j].weight;for (j++; j <= i; j++)if (HT[j].parent == 0 && j != s1&&HT[j].weight<w2)s2 = j, w2 = HT[j].weight;//保持s1<s2if (s1>s2)s = s1, s1 = s2, s2 = s;}//读取文件,并将文件中内容存入FileArray数组中
void ReadFile(char path[], char way[], char* &FileArray, int &FileArraySize){//path文件位置,way文件打开方式(r,w,a...),文件中读取的数据放入FileArray数组中FILE *fp;int i = 0;//根据路径和打开方式打开指定的文件,判断操作是否成功 if ((fp = fopen(path, way)) == NULL){printf("can't open the file");}FileArray = (char*)malloc(FileArraySize *sizeof(char));char ch;while ((ch = fgetc(fp)) != EOF){if (i + 1 == FileArraySize){FileArray = (char*)realloc(FileArray, FileArraySize * 2 *sizeof(char));FileArraySize *= 2;}FileArray[i] = ch;i++;}FileArraySize = i;fclose(fp);  //完成读取以后将文件关闭
}//求每个ASCII码对应字符的权值,并将权值存入weigh数组中
void Weight(char* FileArray, int weight[ASCIISize]){for (int i = 0,m; i < FileArraySize; i++){m = FileArray[i] - 0;weight[m]++;}
}//根据每个字母的权值,创建哈夫曼树,求出哈夫曼编码
void CreateHaffTree(int weight[ASCIISize], HuffmansTree &HT, HuffmanCode &HC){//    int _Select(HuffmansTree, int, int&, int&);int i, m, s1, s2, c, f, start;HuffmansTree p;char *cd;//初始化m = 2 * ASCIISize - 1;HT = (HuffmansTree)malloc((m + 1)*sizeof(HTNode)); //0号单元未用for (p = HT + 1, i = 1; i <= ASCIISize; ++i, ++p) //生成n个叶子结点 NOTE:课本有误p->weight = weight[i],p->flag = 1, p->parent = p->leftChild = p->rightChild = 0, p->ch = i;for (; i <= m; ++i, ++p)p->flag = p->weight = p->parent = p->leftChild = p->rightChild = 0, p->ch = -1;//构造哈夫曼树for (i = ASCIISize + 1; i <= m; ++i){//在HT[1..i-1]中选择两个parent为0且weight最小的,序号为s1,s2_Select(HT, i - 1, s1, s2);//用s1和s2作为左右子树和并成一棵树iHT[s1].parent = HT[s2].parent = i;HT[i].leftChild = s1; HT[i].rightChild = s2;HT[i].weight = HT[s1].weight + HT[s2].weight;}//求哈夫曼编码HC = (HuffmanCode)malloc((ASCIISize + 1)*sizeof(char *));cd = (char *)malloc(ASCIISize*sizeof(char)); //临时工作空间for (i = 1; i <= ASCIISize; ++i){start = ASCIISize - 1;cd[start] = '\0';for (c = i, f = HT[i].parent; f != 0; c = f, f = HT[f].parent)if (HT[f].leftChild == c)cd[--start] = '0';elsecd[--start] = '1';HC[i] = (char*)malloc((ASCIISize - start + 1)*sizeof(char));strcpy(HC[i], &cd[start]);}free(cd);
}//给据已得到的每个字符的哈夫曼编码对整篇文章进行编码,结果存入数组中
void BuildFileCode(char** &FileCode, int &FileCodeSize){FileCode = (char**)malloc(FileCodeSize *sizeof(char *));int n = 0,m = 0,i,j;for (i = 0; i < FileArraySize; i++, n++){m = FileArray[i] - 0;if ( n >= FileCodeSize - 1){FileCode = (char**)realloc(FileCode, FileCodeSize * 2 * sizeof(char*));FileCodeSize *= 2;}FileCode[n] = HC[m];}FileCode[n] = "###";FileCodeSize = n;for (int i = 0; i < --n; i++)printf("%s", FileCode[i]);
}//根据哈夫曼树进行哈夫曼解码,结果存入数组返回
void DecodeHaffTree(HuffmansTree HT, char** FileCode, char* &_FileArray_, int &_FileArraySize_){int root, p, j = 0;p = root = 2 * ASCIISize - 1; //设置遍历开始,根节点 printf("解码后的字符串为:\n");                                                                                                                                                                                                  _FileArray_ = (char*)malloc(FileCodeSize *sizeof(char));for (int i = 0; FileCode[i] != "###"; i++){int m = strlen(FileCode[i]);for (int k = 0; k < m; k++){char fcs = *(FileCode[i]++);if (fcs == '0'){   //如果当前字符为 0 ,则当前节点为原节点的左子 p = HT[p].leftChild;}else if (fcs == '1'){    //如果当前字符为 1 ,则当前节点为原节点的右子 p = HT[p].rightChild;}if (HT[p].flag == 1){ //如果当前节点既没有左子,又没有右子,则将对应的字符存入编码数组_FileArray_[j++] = HT[p].ch;//printf("%c", HT[p].ch);p = root; //重新回到根节点,继续解码 }}}
}//储存文件,将array数组中的元素存入文件中,array包括FileCode和_FileArray
void WriteFile(char path[], char way[], char* array){FILE *fp;fp = fopen(path, way);fputs(array, fp);fclose(fp);
}int main(void){ReadFile("F:\\read.txt", "r", FileArray, FileArraySize);Weight(FileArray, weight);CreateHaffTree(weight,HT, HC);BuildFileCode(FileCode, FileCodeSize);DecodeHaffTree(HT, FileCode, _FileArray_, _FileArraySize_);WriteFile("F:\\write.txt", "a", _FileArray_);getchar();
}

程序中只做了对解码后文章的储存,没有做对编码字符串和哈夫曼树的储存

程序中各种命名混乱加不规则,各位就将就着看看吧

不限文章大小!英文文章的编码和解码(C语言,哈夫曼编码)相关推荐

  1. 对哈夫曼编码的输出 c语言,哈夫曼编码问题

    哈夫曼编码问题 代码由bug求改进 #include #include #include using namespace std; #define Max 200 //最大结点数目 #define I ...

  2. C语言哈夫曼编码压缩解压

    C语言哈夫曼编码压缩解压 一.实验目的 掌握哈夫曼编码基本运算以及存储结构表示. 二.实验内容: 1.系统要求包含以下功能 1)初始化:从终端读入字符集大小n,以及n个字符和n个权值(或者读入字符集和 ...

  3. 数据结构c语言哈夫曼编码译码系统,数据结构C语言哈夫曼编码译码

    <数据结构C语言哈夫曼编码译码>由会员分享,可在线阅读,更多相关<数据结构C语言哈夫曼编码译码(16页珍藏版)>请在人人文库网上搜索. 1.实训报告题 目: 哈夫曼树编码译码院 ...

  4. C语言霍夫曼编码压缩,数据结构大作业——哈夫曼编码压缩BMP格式文件

    数据结构大作业--哈夫曼编码压缩BMP格式文件 首先需要了解BMP图像格式 BMP图像格式详解 其次需要了解哈夫曼编码如何对BMP文件进行压缩 哈夫曼压缩与解压缩 编程部分 使用的头文件 虽然这里用了 ...

  5. 信息论霍夫曼编码c语言,霍夫曼编码

    <信息论与编码>课程实验报告 姓 名 学 号 单 位 专 业 2014 年 12 月 4 日 实验一 一.实验目的 1.理解信源编码的意义: 2.掌握霍夫曼编码的方法及计算机实现: 二.实 ...

  6. 夫曼编码译码系统课程设计实验报告(含源代码c++_c语言),哈夫曼编码译码系统课程设计实验报告(含源代码C++_C语言)[1]...

    目 录 摘 要 ---------------------------..------ II Abstract ----------------------------..---... II 第一章 ...

  7. 霍夫曼编码代码matlab,matlab 实现霍夫曼编码

    编码内容包括:用matlab实现霍夫曼编码,并且求出相应的信源熵,平均码长,和编码效率. 以下是代码: %霍夫曼编码 %huffman_code %编码思路:根据位置矩阵的变化过程反推生成霍夫曼编码 ...

  8. huffman编码译码器用c语言,基于哈弗曼编码的数据压缩C语言实现

    haod 摘要 数据压缩技术是一项重要实用的信息技术.信息时代的到来,信息量迅速增长,使得数据压缩也显得越来越重要.数据压缩有多种编码方法,大致可分为无损压缩编码和有损压缩编码.其中,Huffman ...

  9. 信息论霍夫曼编码c语言,霍夫曼编码C语言

    编译成功 /* Note:Your choice is C IDE */ #include #include #define N 15 #define M 2*N-1 typedef struct { ...

  10. 哈夫曼编码/译码器:设计一个哈夫曼编码/译码系统,对一个文本文件中的字符进行哈夫曼编码,生成编码文件;反过来,可将一个编码文件译码还原为一个文本文件(.txt)。要求:① 输入一个待压缩的文本文件名

    目录 1.实验题目 2.概要设计 2.1 问题分析 2.2 流程图 2.3 功能模块 3.详

最新文章

  1. MindSpore部署图像分割示例程序
  2. 一款名为Blue_Moon的后台模板的初步研究
  3. Spring XD 1.1 M2 and 1.0.3 released---support kafka
  4. mysql 1054 42s22_MySQL ERROR 1054(42S22)
  5. pdfbox java.lang.outofmemoryerror_Apache PDFBox 1.8.11 发布,Java 的 PDF 处理类
  6. java web 自定义异常_Java web, service 层应该通过异常(自定义Exception)来中断业务吗?...
  7. 【MATLAB】求点到多边形的最短距离
  8. android 4.2 安全新特性(I)
  9. cmake构建NNIE工程
  10. 调查问卷java源码_2020年Java技术趋势
  11. 多数iPhone应用程序的不足之处
  12. mac下cordova的ios-deploy安装问题
  13. Navicat连接Mysql报错:Client does not support authentication protocol requested by server;
  14. c语言计算器程序代码有优先级,C语言计算器小程序(源代码+实习报告).doc
  15. 出版了两本实体书,写了9本开源电子书,还上了百度百科,冰河这是要起飞了吗?(建议收藏)
  16. wps如何用循环函数_wps表格函数怎么用 wps表格函数的简单用法分享
  17. 计算机专业英语教程(第二版)
  18. [SPSS]典型相关分析的SPSS实现——开卷和闭卷学科成绩的典型相关分析实例
  19. labview与单片机正弦信号_基于LabVIEW的正弦信号频率与相位测量.doc
  20. SOA实施妙方 以CRM为切入点

热门文章

  1. 从光学成像到计算光学成像
  2. 据说比谷哥牛的搜索引擎
  3. 厦门有哪些靠谱的互联网公司
  4. JQ获取元素的父子兄弟级
  5. 已经建好的表添加唯一性约束、主键、外键约束
  6. 浏览器加载解析渲染机制的全面解析
  7. HDU 3105 Fred's Lotto Tickets(数学题)
  8. 呐,c语言学习你想要的都在这里
  9. linux centos 7 系统性能查询、DHCP租期信息查询、网络五元组
  10. m基于MATLAB的上行链路MIMO关键技术的研究与性能分析