- 1、本文档共16页,可阅读全部内容。
- 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
哈夫曼编码译码器
哈夫曼编码译码器
需求分析:
一个完整的系统应具有以下功能:
(l)I:初始化。从终端读入字符集大小n,及n个字符和n个权值,建立哈夫曼树,并将它存于文件hfmtree中。
(2)C:编码。利用已建好的哈夫曼树(如不在内存,则从文件hfmtree中读入),对文件tobetrans中的正文进行编码,然后将结果存入文件codefile中。
(3)D:编码。利用已建好的哈夫曼树将文件codefile中的代码进行译码,结果存入文件textfile中。
(4)P:印代码文件。将文件codefile以紧凑格式显示在终端上,每行50个代码。同时将此字符形式的编码文件写入文件codeprint中。
(5)T:印哈夫曼树。将已在内存中的哈夫曼树以直观的方式 (树或凹入表形式)显示在终端上,同时将此字符形式的哈夫曼树写入文件treeprint中
字符
__
A
B
C
D
E
F
G
H
I
J
K
L
M
频度
186
64
23
22
32
103
21
15
47
57
1
5
32
20
字符
N
O
P
Q
R
S
T
U
V
W
X
Y
Z
?
频度
20
56
19
2
50
51
55
30
10
11
2
21
2
?
可以根据题目要求把程序划成5个模块,设计成菜单方式,每次执行一个模块后返回菜单。
除了初始化(I)过程外,在每次执行时都经过一次读取磁盘文件数据。这是为了如果在程序执行后一直没有进行初始化(I)过程,为了能使后面的操作顺利进行,可以通过读取旧的数据来进行工作。比如:如果程序的工作需要的字符集和权值数据是固定的,只要在安装程序时进行一次初始(I)化操作就可以了。在再次运行程序时,不管进行那项操作都可以把需要的数据读入到内存。
?b)概要设计
本程序主要用到了三个算法。
(1)哈夫曼编码
在初始化(I)的过程中间,要用输入的字符和权值建立哈夫曼树并求得哈夫曼编码。先将输入的字符和权值存放到一个结构体数组中,建立哈夫曼树,将计算所得的哈夫曼编码存储到另一个结构体数组中。
(2)串的匹配
在编码(D)的过程中间,要对已经编码过的代码译码,可利用循环,将代码中的与哈夫曼编码的长度相同的串与这个哈夫曼编码比较,如果相等就回显并存入文件。
(3)二叉树的遍历
在印哈夫曼树(T)的中,因为哈夫曼树也是二叉树,所以就要利用二叉树的先序遍历将哈夫曼树输出
c)详细设计
构造树的方法如下: ?
初始化:每个字符就是一个结点,字符的频度就是结点的权; ? ? 1、将结点按频度从小到大排序; ? ? 2、选取频度最小的 ? 两个结点,以它们为儿子,构造出一个新的结点; ? ? ? ? ? 新结点的权值就是 ? 它两个儿子的权值之和; ? ? ? ? ? 构造之后,从原来的结点序列里删除刚才选出的那两个结点,但同时将新生成的结点加进去; ? ? 3、如果结点序列里只剩下一个结点,表示构造完毕,退出。 ? ? ? ? ? 否则回到第一步。
编码: ? ? 上面已经生成了树,接着就该对该树进行编码了。 ? ? 可以假定,对某个结点而言,其左孩子在当前阶段的编码为 ? 0,右孩子的编码为 ? 1。这样就可以通过“树的遍历”的方式来生成?? 字符——编码 ? 对照表。
? 来到这里,基本上艰苦的已经完成了,对某个具体的字符串编码和解码就只是简单的“查表——替换”的工作了。 ? 解码: ? ? ? ? 解码也是个简单的查表--替换过程。如果利用该种编码发送字符串,则它的“字符——编码”对应表也必须发送过去,不然对方是不知道怎么解码的。 ? ? ? ? 对给出的一串编码,从左向右,将编码组合起来并查表,“一旦”找到有匹配的 ? 字符,则马上将当前的 ? 编码 ? 替换为 ? 对应的字符。 ? ? ? ? 因为该编码是不会出现 ? “某一个字符的编码 ? 是 ? 另一个字符编码 ? 的前缀” ? 这种情况的,也就是不会出现类似于“A ? 00 ? ? B ? 0010” ? 这样的情况,所以解码出来的字符串是唯一的,而且就是原来进行编码的那一个。
程序如下
#includeiostream
#includefstream
#includestring
using namespace std;
struct HuffmanNode //定义哈夫曼树各结点
{
int weight; //存放结点的权值,假设只考虑处理权值为整数的情况
int parent; //记录结点父亲位置,-1表示为根结点,否则表示为非根结点
int lchild,rchild; //分
文档评论(0)