• 哈夫曼数的构建,编码代码


    #include<bits_stdc++.h>
    using namespace std;
    typedef struct //huffmantree node
    {
    int w;
    int p,lc,rc;
    }hmnode,hftree;
    typedef char **hfcode;//编码表
    void tsort(hftree t[],int n,int &s1,int &s2)
    {
    int h,j;//提出变量
    for(h=0;h<n;h++)
    if(t[h].p==0)
    {s1=h;break;}
    for(j=h+1;j<n;j++)
    if(t[j].p==0&&t[j].w<t[s1].w)
    s1=j;
    for(h=0;h<n;h++)
    if(t[h].p==0&&h!=s1)
    {s2=h;break;}
    for(j=h+1;j<n;j++)
    if(t[j].p==0&&t[j].w<t[s2].w&&j!=s1)//j!=s
    s2=j;
    }
    void savetree(hftree t[],int n)//save huffmantree
    {
    int m=2*n-1;
    ofstream pout("hfmtree.txt");
    if(!t)
    return;
    for(int i=0;i<m;i++)
    {
    pout<<t[i].w<<endl;
    }
    }
    void inithfmtree(hftree t[],int *w,int n)//initialize huffmantree
    {
    for(int i=0;i<n;i++)
    {
    t[i].w=w[i];
    t[i].p=0;//可以=child
    t[i].lc=t[i].rc=-1;//不能=0,第一个元素也为零,循环会无限进行
    }
    for(i=n;i<2*n-1;i++)
    {
    t[i].w=0;
    t[i].p=0;
    }
    }
    void creathf(hftree t[],hfcode &hc,int n)//creat
    {
    int s1=0,s2=0,a=0,i;
    for(i=n;i<2*n-1;i++)
    {
    tsort(t,n+a,s1,s2);
    t[s1].p=i;
    t[s2].p=i;
    t[i].lc=s1;
    t[i].rc=s2;
    t[i].w=t[s1].w+t[s2].w;a++;
    }//构建huffman tree
    savetree(t,n);
    hc=(hfcode)malloc(n*sizeof(char *));
    char *cd=(char *)malloc(n*sizeof(char));
    cd[n-1]='';
    int s,c,k;
    for(i=0;i<n;i++)
    {
    s=n-1;
    for(c=i,k=t[i].p;k!=0;c=k,k=t[k].p)//int c=i,k=t;k前不需要再加int!
    {
    if(t[k].lc==c) cd[--s]='0';//逆求
    else cd[--s]='1';
    }
    hc[i]=(char *)malloc((n-s)*sizeof(char));//开创n-s,记录
    strcpy(hc[i],cd+s);//strcpy用法!!

    }
    }
    void encode(hfcode &hc,char *ch,int n)//code
    {
    cout<<"文件内容为:"<<endl;
    char c;
    char f[100];
    int a=0;
    fstream in;
    in.open("tobetran.txt",ios::in);//文件操作,fstream in ;in.open(,)
    while((c=in.get())!=EOF)
    {
    f[a]=c;a+=1;
    cout<<c;
    }
    in.close();
    cout<<endl<<"编码后为:"<<endl;
    ofstream out("codefile.txt");
    for(int i=0;i<a;i++)
    {
    for(int j=0;j<n;j++)//二重循环对比f,ch
    {
    if(f[i]==ch[j])
    {
    cout<<hc[j];
    out<<hc[j];
    }
    }
    }
    cout<<endl;
    out.close();
    }
    void decodeing(hftree t[],int n,char *ch)//decode
    {
    cout<<"文件内编码:"<<endl;
    char c;
    char p[100];
    int m=2*n-2;//数组从0开始,-2!
    int a=0;
    fstream in;
    in.open("codefile.txt",ios::in);
    while((c=in.get())!=EOF)
    {
    cout<<c;
    p[a]=c;
    a++;
    }
    in.close();
    p[a]='$';// end-mark
    cout<<endl<<"译码:"<<endl;
    fstream out("textfile.txt");
    int i;
    for(i=0;p[i]!='$';i++)//i++就可以
    {
    if(p[i]=='0')
    {
    m=t[m].lc;
    }
    else if(p[i]=='1')
    {
    m=t[m].rc;
    }
    if(t[m].lc==-1&&t[m].rc==-1)
    {
    cout<<ch[m];
    out<<ch[m];//input to file
    m=2*n-2;//返回根节点
    }
    }
    out.close();
    }
    void print()//print the code
    {
    fstream in,pout;
    in.open("codefile.txt",ios::in);
    pout.open("codeprint.txt",ios::out);
    int ct=0;
    char c;
    while((c=in.get())!=EOF)
    {
    cout<<c;
    pout<<c;
    ct++;
    if(ct%50==0)
    {
    pout<<endl;
    }
    }
    in.close();//close the file
    pout.close();
    }
    void treeprint()//print the tree
    {
    fstream pout,in;
    pout.open("treeprint.txt",ios::out);
    in.open("hfmtree.txt",ios::in);
    char c;
    cout<<endl<<"打印树:"<<endl;
    while((c=in.get())!=EOF)
    {
    cout<<c;
    pout<<c;
    }
    in.close();
    pout.close();
    }
    int main()
    {
    int n;
    cout<<"请输入字符个数:"<<endl;
    cin>>n;
    int *w;
    char *ch;
    w=(int*)malloc(n*sizeof(int));
    ch=(char*)malloc(n*sizeof(char));
    cout<<"请输入字符及权值:"<<endl;
    for(int i=0;i<n;i++)
    {
    cout<<"char:"<<endl;
    cin>>ch[i];
    cout<<"weight:"<<endl;
    cin>>w[i];
    }
    hftree t[20];//结构体数组
    hfcode hc;//char **hc
    inithfmtree(t,w,n);
    creathf(t,hc,n);
    encode(hc,ch,n);
    decodeing(t,n,ch);
    print();
    treeprint();
    return 0;
    }//指针、malloc、函数传递

    朝闻道
  • 相关阅读:
    Spark源码走读6——Shuffle
    Spark源码走读5——Storage
    使用Gradle构建Android应用的渠道包
    轻松搞定面试中的二叉树题目
    QT中使用微软Speech API实现语音识别
    QT 相关资源(书籍、论坛、博客等。。。)整理...
    使用Cscope阅读大型工程Linux内核的源代码教程
    搭建一个免费的,无限流量的Blog----github Pages和Jekyll入门
    RSA算法原理(二)
    RSA算法原理(一)
  • 原文地址:https://www.cnblogs.com/wander-clouds/p/8443700.html
Copyright © 2020-2023  润新知