回 帖 发 新 帖 刷新版面

主题:急救“哈夫曼编/译码”程序

非常恳切地请求援助~~~~~~~~~~~~~~
[问题描述]
利用哈夫曼编码进行通信可以大大提高信道利用率,缩短信息传输时间,降低传输成本。但是,这要求在发送端通过一个编码系统对待传数据预先编码,在接收端将传来的数据进行译码(复原)。对于双工信道(即可以双向传输信息的信道),每端都需要一个完整的编/译码系统。试为这样的信息收发站写一个哈夫曼码的编/译码系统。
[基本要求]
一个完整的系统应具有以下功能:
(1)I:初始化(Initialization)。从终端读入字符集大小n,以及n个字符和n个权值,建立哈夫曼树,并将它存于文件hfmTree中。
(2)E:编码(Encoding)。利用已建好的哈夫曼树(如不在内存,则从文件hfmTree中读入),对文件ToBeTran中的正文进行编码,然后将结果存入文件CodeFile中。
(3)D:译码(Decoding)。利用已建好的哈夫曼树将文件CodeFile中的代码进行译码,结果存入文件TextFile中。
(4)P:印代码文件(Print)。将文件CodeFile以紧凑格式显示在终端上,每行50个代码。同时将此字符形式的编码文件写入文件CodePrin中。
(5)T:印哈夫曼树(Tree printing)。将已在内存中的哈夫曼树以直观的方式(树或凹入表形式)显示在终端上,同时将此字符形式的哈夫曼树写入文件TreePrint中。
[测试数据]
(1)利用下面这道题中的数据调试程序。
某系统在通信联络中只可能出现八种字符,其概率分别为0.25,0.29,0.07,0.08,0.14,0.23,0.03,0.11,试设计哈夫曼编码。
(2)用下表给出的字符集和频度的实际统计数据建立哈夫曼树,并实现以下报文的编码和译码:“THIS PROGRAM IS MY FAVORITE”。
字符 空格  A   B   C   D   E   F   G   H   I   J   K   L   M
频度 186   64  13  22  32 103  21  15  47  57  1   5   32  20
字符  N    O   P   Q   R   S   T   U   V   W   X   Y   Z
频度  57   63  15  1   48  51  80  23  8   18  1   16  1

[实现提示]
(1) 编码结果以文本方式存储在文件CodeFile中。
(2) 用户界面可以设计为“菜单”方式:显示上述功能符号,再加上“Q”,表示退出运行Quit。请用户键入一个选择功能符。此功能执行完毕后再显示此菜单,直至某次用户选择了“Q”为止。
(3) 在程序的一次执行过程中,第一次执行I,D或C命令之后,哈夫曼树已经在内存了,不必再读入。每次执行中不一定执行I命令,因为文件hfmTree可能早已建好。

[color=FF0000][/color]

回复列表 (共12个回复)

11 楼

#include<iostream>
#include<string>
using namespace std;
typedef struct 
{
    int weight;
    int flag;
    int parent;
    int lchild;
    int rchild;
}hnodetype;
typedef struct 
{
    int bit[10];
    int start;
    char leaf;
}hcodetype;
void huf(char cha[],int m[],int n)
{
    int i,j,m1,m2,x1,x2,c,p;
    hnodetype *huffnode=new hnodetype[2*n-1];
    hcodetype *huffcode=new hcodetype[n],cd;
    for(i=0;i<2*n-1;i++)
    {
        huffnode[i].weight=0;
        huffnode[i].parent=0;
        huffnode[i].flag=0;
        huffnode[i].lchild=-1;
        huffnode[i].rchild=-1;
    }
    for(i=0;i<n;i++)
    {
        huffnode[i].weight=m[i];
        huffcode[i].leaf=cha[i];
    }
    for(i=0;i<n-1;i++)
    {
        m1=m2=10000000;
        x1=x2=0;
        for(j=0;j<n+i;j++)
        {
            if(huffnode[j].weight<=m1&&huffnode[j].flag==0)
            {
                m2=m1;
                x2=x1;
                m1=huffnode[j].weight;
                x1=j;
            }
            else if(huffnode[j].weight<=m2&&huffnode[j].flag==0)
            {
                m2=huffnode[j].weight;
                x2=j;
            }
        }
        huffnode[x1].parent=n+i;
        huffnode[x2].parent=n+i;
        huffnode[x1].flag=1;
        huffnode[x2].flag=1;
        huffnode[n+i].weight=huffnode[x1].weight+huffnode[x2].weight;
        huffnode[n+i].lchild=x1;
        huffnode[n+i].rchild=x2;
    }
    for(i=0;i<n;i++)
        {
            cd.start=n-1;
            c=i;
            p=huffnode[c].parent;
            while(p!=0)
            {
                if(huffnode[p].lchild==c)
                    cd.bit[cd.start]=0;
                else
                    cd.bit[cd.start]=1;
                cd.start--;
                c=p;
                p=huffnode[c].parent;
            }
            cout<<huffcode[i].leaf<<":";
            for(j=cd.start+1;j<n;j++)
            {
                huffcode[i].bit[j]=cd.bit[j];
                cout<<cd.bit[j];
            }
            cout<<endl;
            huffcode[i].start=cd.start;
    }
    delete[] huffcode;
    delete[] huffnode;
}
void main()
{
    string str;
    int i=0,j,n,m[100],h,k=0;
    char cha[100];
    cout<<"请输入一个字符串"<<endl;
    cin>>str;
    n=str.length();
    cout<<"字符串总共有字符"<<n<<"个"<<endl;
    for(i=0;i<n;i++)
    {
        j=0;h=0;
        while(str[i]!=str[j])
            j++;
        if(j==i)
        {
        cha[k]=str[i];
        cout<<"字符"<<cha[k]<<"出现";
        }
        else
            continue;
        for(j=i;j<n;j++)
        {
            if(str[i]==str[j])
                h++;
        }
        cout<<h<<"次"<<endl;
        m[k]=h;
        k++;
    }
    cout<<"每个字符的哈夫曼编码是:"<<endl;
    huf(cha,m,k);
    cin.get();
    cin.get();
    
}

12 楼

刚好搜到这个网页,写的很详细,我不想贪功,自己去看:
http://zdker.blog.163.com/article/-Uqdk-tIe8u-.html

我来回复

您尚未登录,请登录后再回复。点此登录或注册