3. 哈夫曼编码/译码系统(树应用)

[ 题目描述 ]
利用哈夫曼编码进行通信,可以压缩通信的数据量,提高传输效率,缩短信
息的传输时间,还有一定的保密性。现在要求编写一程序模拟传输过程,实现在
发送前将要发送的字符信息进行编码,然后进行发送,接收后将传来的数据进行
译码,即将信息还原成发送前的字符信息。
现在有两个功能:
1 发送者:将待传送的字符信息转化为哈夫曼编码。
2 接受者:将接受的编码信息进行译码,得到还原成发送前的字符信息。
[ 输入 ]
输入一个小写字母组成的字符串 S(1<=strlen(S)<=1e3) ,表示待传送的字符
4 串。
[ 输出 ]
输出为两行,第一行将输入的字符串转化为哈夫曼编码的长度。第二行输出
哈夫曼编码译码的长度

哈夫曼编码:
   #include<iostream>
#include<cstring>

using namespace std;

typedef struct{
    char data;
    int weight;
    int parent, left, right;
}HTNode, *HuffmanTree;

int n;
char a[1005];
int b[1005] = {0};
string s;

void Select(HuffmanTree &HT, int end, int *s1, int *s2)
{
    int min1, min2;
    int i = 1;
    while(HT[i].parent != 0 && i <= end){
        i++;
    }
    min1 = HT[i].weight;
    *s1 = i;
    i++;
    while(HT[i].parent != 0 && i <= end){
        i++;
    }
    if(HT[i].weight < min1){
        min2 = min1;
        *s2 = *s1;
        *s1 = i;
        min1 = HT[i].weight;
    }else{
        *s2 = i;
        min2 = HT[i].weight;
    }
    for(int j = i+1; j <= end; j++){
        if(HT[j].parent != 0) continue;
        if(HT[j].weight < min1){
            min2 = min1;
            *s2 = *s1;
            *s1 = j;
            min1 = HT[j].weight;
        }else  if(HT[j].weight >= min1 && HT[j].weight < min2){
            min2 = HT[j].weight;
            *s2 = j;
        }
    }
}


void CreatHuffman(HuffmanTree &HT){
    cout<<"请输入字符信息:\n";
    cin>>s;
    int k = 1;
    int cunt = s.length();
    for(int i = 0; i < cunt; i++){
        int j = 1;
        for(j = 1; j < k; j++){
            if(s[i] == a[j]){
                b[j]++;
                break;
            }
        }
        if(j == k){
            a[k] = s[i];
            b[k]++;
            k++;
        }
    }
    n = k-1;
    if(n <= 1) return;
    int m = 2*n-1;
    HT = (HTNode*)malloc(sizeof(HTNode)*(2*n));
    for(int i = 1; i <= n; i++){
        HT[i].weight = b[i];
        HT[i].parent = 0;
        HT[i].left = 0;
        HT[i].right = 0;
        HT[i].data = a[i];
    }
    for(int i = n+1; i <= m; i++){
        HT[i].weight = 0;
        HT[i].parent = 0;
        HT[i].left = 0;
        HT[i].right = 0;
    }
    for(int i = n+1; i <= m; i++){
        int s1,s2;
        Select(HT,i-1,&s1,&s2);
        HT[i].left = s1;
        HT[i].right = s2;
        HT[i].weight = HT[s1].weight + HT[s2].weight;
        HT[s1].parent = i;
        HT[s2].parent = i;
        
    }
}

typedef char** huffmanCode;    //第一个*是代表它是指针变量,说明它是数组
//第二个*说明它是指针数组,代表这个char类型数组里每个元素都是*huffmanCode变量
void HuffmanCode(HuffmanTree HT, huffmanCode &HC){
    HC = (huffmanCode)malloc(sizeof(huffmanCode)*(n+1));
    char* cd = (char*)malloc(sizeof(char) * n);
    int start = 0, c = 0, f = 0;
    cd[n-1] = '\0';
    for(int i = 1; i <=  n; i++){
        start = n-1;
        c = i;
        f = HT[i].parent;
        while(f != 0){
            start--;
            if(HT[f].left == c){
                cd[start] = '0';
            }else{
                cd[start] = '1';
            }
            c = f;
            f = HT[c].parent;
        }
        HC[i] = (char*)malloc(sizeof(char) * (n - start));
        strcpy(HC[i],&cd[start]);
    }
    free(cd);
}


int main()
{
    HuffmanTree HT;
    huffmanCode HC;
    CreatHuffman(HT);
    HuffmanCode(HT,HC);
    cout<<n<<"\n";
    for(int i = 1; i <= n; i++){
        cout<<HT[i].data<<":"<<HC[i]<<"\n";
    }
    for(int i = 0; i < s.length(); i++){
        for(int j = 1; j <=n; j++){
            if(s[i] == HT[j].data){
                cout<<HC[j]<<" ";
            }
        }
    }
    cout<<"\n";
    string ss;
    cout<<"请输入想要解码的信息:\n";
    cin>>ss;
    string sss;
    for(int i = 0; i < ss.length(); i++){
        sss += ss[i];
        for(int j = 1; j <= n; j++){
            if(sss ==  HC[j]){
                sss.clear();
                cout<<HT[j].data;
            }
        }
    }
    return 0;
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值