哈夫曼树编码与译码

这是数据结构课程综合设计的一道题目,要求实现哈夫曼编码与译码。

题目三

哈夫曼编码/译码器

     根据给定的一组电文,设计该电文的哈夫曼编码。

基本要求:

   1)初始化(Initialization):从终端读入字符集,大小n,随机产生包含n个字符的字符集存入文件中,然后统计每个字符出现的次数作为各字符的权值,以此建立哈夫曼树;

     (2)编码(Coding):根据建立的哈夫曼树,对数据进行编码,然后将结果存入文件codefile中;

     (3)译码(Decoding):利用已建好的哈夫曼树将文件codefile中的代码进行译码,结果存入文件textfile中。

测试数据要求:

     随机产生的字符要足够多,不允许手工输入。  

【代码】
#include<bits/stdc++.h>
using namespace std;
const int INF=1010100;
struct node{
    char ch;
    int val;//字符ch出现的次数
    node *l,*r;
};
void MakeStrFile(int n)//产生随机字符串文件(仅小写)
{
    ofstream fout("str.txt");
    while(n--){
        char ch=rand()%26+'a';
        cout<<ch;
        fout<<ch;
    }
    cout<<endl;
    fout.close();
}
node* MakeTree()//构造哈夫曼树(同时生成映射数组M)
{
    ifstream fin("str.txt");
    int c[128]={0};//统计每隔字符出现的次数
    for(char ch;fin>>ch;c[ch]++);
    node *vec[26];//结点的指针
    int top=0;
    for(int i='a';i<='z';i++)if(c[i])
    {
        node *p=new node;
        p->ch=i;
        p->val=c[i];
        p->l=p->r=NULL;
        vec[top++]=p;
    }
    while(top>1)//构造哈夫曼树
    {
        for(int i=top-2;i<top;i++)//把最小的两个元素移动到末尾
        {
            for(int j=0;j<i;j++)
                if(vec[j]->val<vec[i]->val)
                    swap(vec[j],vec[i]);
        }
        node *p=new node;
        p->ch='\0';//非叶子,空字符
        p->val=vec[top-1]->val + vec[top-2]->val;
        p->l=vec[--top];
        p->r=vec[--top];
        //合并了结点
        vec[top++]=p;//产生新父节点
    }
    return vec[0];//根节点
}
void MakeMap(node *rt,map<char,string> &Map,char s[],int deep)
{//由树产生映射Map
    if(rt->ch == '\0')//非叶子
    {
        s[deep]='0';
        MakeMap(rt->l,Map,s,deep+1);
        s[deep]='1';
        MakeMap(rt->r,Map,s,deep+1);
    }
    else //叶子
    {
        s[deep]='\0';
        Map[rt->ch]=string(s);
        cout<< rt->ch <<" "<< s <<endl;
        return;
    }
}
void Coding(char *str,char *code,node *rt)
{
    ifstream fin(str);
    ofstream fout(code);
    map<char,string>M;//字符映射编码
    char s[128];
    cout<<"映射关系:"<<endl;
    MakeMap(rt,M,s,0);//由树产生映射
    char ch;
    cout<<"编码:"<<endl;
    while(fin>>ch)
    {
        fout<<M[ch];
        cout<<M[ch];
    }
    cout<<endl;
}
void Decoding(char *code,char *out,node *rt)//译码
{
    node *p=rt;
    ifstream fin(code);
    ofstream fout(out);
    cout<<"译码:"<<endl;
    for(char ch;fin>>ch;)
    {
        p= ch=='0'? p->l:p->r;
        if(p->ch)//叶子
        {
            fout<<p->ch;
            cout<<p->ch;
            p=rt;//回到根
        }
    }
    cout<<endl;
}
int main()
{
    srand(time(0));
    int n;
    cout<<"输入随机字符串长度:";
    cin>>n;
    MakeStrFile(n);//产生随机字符->str.txt
    node *rt=MakeTree();//生成哈夫曼树
    Coding("str.txt","codefile.txt",rt);//编码form str to codefile
    Decoding("codefile.txt","textfile.txt",rt);//译码from codefile to textfile
}

【测试运行】:

  • 2
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

雪的期许

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值