第一次写树。。。纯当纪念吧。。只有1个节点要特判内牛满面。。

#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
using namespace std;
struct Node
{
    int lc,rc,pa;
    int val;
    int pos;
    char s[20];
    char str;
}a[10000];
bool operator> (const Node& x, const Node &y)
{
	return x.val > y.val;
}
void init(int n)
{
    int i;
    for(i=n+1;i<=n*2-1;i++)
        a[i].lc=a[i].rc=a[i].pa=-1,a[i].pos=i,a[i].val=0;
}

char ss[1000];
int vis[1000],Sum;

void build(int x,int level)
{
    if(a[x].lc!=-1)
    {
        ss[level]='0';
        build(a[x].lc,level+1);
    }
    if(a[x].rc!=-1)
    {
        ss[level]='1';
        build(a[x].rc,level+1);
    }
    if(a[x].lc==a[x].rc)
    {
        ss[level]='/0';
        strcpy(a[x].s,ss);
    }
}
void search(char s[],int n)
{
    if(a[n].lc==a[n].rc)
    {
        cout<<a[n].str;
        return ;
    }
    int k=Sum++;
    if(s[k]=='1')
    {
        search(s,a[n].rc);
        return;
    }
    else if(s[k]=='0')
        search(s,a[n].lc);
    return;
}
int find(int c,char Str[],int cnt)
{
    int count=0;
    Sum=0;
    while(Sum<c)
    {
        search(Str,cnt);
        if(cnt==1) Sum++;
        count++;
    }
    return count;
}
int main()
{
    char str[10000],Str[10000];
    int len,cnt=0,i,j;
    cout<<"请输入要转变的字符串:/n";
    cin.getline(str,1000);
    priority_queue<Node, vector<Node>,greater<vector<Node>::value_type> > Q;
    memset(vis,0,sizeof vis);
    len=strlen(str);
    for(i=0;i<len;i++)
    {
        if(!vis[str[i]])
        {
            vis[str[i]]=++cnt;
            a[cnt].val=1;
            a[cnt].str=str[i];
            a[cnt].lc=a[cnt].rc=a[cnt].pa=-1;
            a[cnt].pos=cnt;
        }
        else a[vis[str[i]]].val++;
    }
    init(cnt);
    cout<<"每个字符出现的次数:/n";
    for(i=1;i<=cnt;i++)
    {
        Q.push(a[i]);
        printf("%c:%02d/t",a[i].str,a[i].val);
        if(i%4==0) cout<<endl;
    }
    if(cnt%4!=0) cout<<endl;
    int x,y,sum=cnt;
    for(i=1;i<sum;i++)
    {
        x=Q.top().pos;//cout<<a[x].val<<endl;
        Q.pop();
        y=Q.top().pos;//cout<<a[y].val<<endl;
        Q.pop();
        cnt++;
        a[cnt].val=a[x].val+a[y].val;
        a[cnt].lc=x;a[cnt].rc=y;
        a[x].pa=cnt;a[y].pa=cnt;
        Q.push(a[cnt]);
    }
    build(cnt,0);
    cout<<"树构造: "<<endl;
    for(i=1;i<=cnt;i++)
        printf("(%02d) father:%02d leftchild:%02d rightchild:%02d val:%d/n",i,a[i].pa,a[i].lc,a[i].rc,a[i].val);
    puts("每个字符转换的代码:");
    if(cnt==1) a[1].s[0]='0',a[1].s[1]=0;
    for(i=1;i<=sum;i++)
        printf("%c:%s/n",a[i].str,a[i].s);
    printf("按回车键的得到编码:");getchar();
    int c=0;
    for(i=0;i<len;i++)
    {
        for(j=0;j<strlen(a[vis[str[i]]].s);j++)
            Str[c++]=a[vis[str[i]]].s[j];
    }
    str[c]='/0';
    for(i=0;i<c;i++)
        cout<<Str[i];
    cout<<endl;
    //cout<<Str<<endl;
    printf("按回车键的得到该码译码:");getchar();
    find(c,Str,cnt);
    puts("");
    printf("原代码长度:%d/n压缩代码长度:%d/n压缩比为:%.1lf%%/n",len*8,c,(double)(c)/(len*8)*100);
    printf("输入要翻译的代码数量:");
    int num;
    cin>>num;
    for(i=1;i<=num;i++)
    {
        cin>>Str;
        c=strlen(Str);
        cout<<"原码为:";
        len=find(c,Str,cnt);
        puts("");
        printf("原代码长度:%d/n压缩代码长度:%d/n压缩比为:%.1lf%%/n",len*8,c,(double)(c)/(len*8)*100);
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值