05-树9 Huffman Codes(30 分)

05-树9 Huffman Codes(30 分)
In 1953, David A. Huffman published his paper “A Method for the Construction of Minimum-Redundancy Codes”, and hence printed his name in the history of computer science. As a professor who gives the final exam problem on Huffman codes, I am encountering a big problem: the Huffman codes are NOT unique. For example, given a string “aaaxuaxz”, we can observe that the frequencies of the characters ‘a’, ‘x’, ‘u’ and ‘z’ are 4, 2, 1 and 1, respectively. We may either encode the symbols as {‘a’=0, ‘x’=10, ‘u’=110, ‘z’=111}, or in another way as {‘a’=1, ‘x’=01, ‘u’=001, ‘z’=000}, both compress the string into 14 bits. Another…

这题目确实厉害,要用到好多数据结构
看着太烦了,想想真让我写我肯定写不出,这里介绍C++解决的方法
源程序借鉴前人的博客
优先队列

#include <iostream>
#include <queue>
#include <algorithm>
#include <cstring>
#include <cstdio>
using namespace std;
struct input
{
    char ch;
    int weight;
}in[100];//初始序列,确定字符和频率(权重)
struct check
{
    char ch;
    string code;
}ck[100];//等待检测的序列
bool cmp(check a,check b){
    return a.code.size()<b.code.size();//长度从小到大排列
}
int cnt(char ch,int N){//查找ch这个字符在原始序列中的位置
    for(int i=0;i<N;i++){
        if(in[i].ch==ch){
            return i;
        }
    }
    return -1;
}
bool frontSq(int n){//先排序,再判断是否有这样的一个string,他是另一个string的前缀
    sort(ck,ck+n,cmp);
    for(int i=0;i<n;i++){
        string temp=ck[i].code;
        for(int j=i+1;j<n;j++){
            if(ck[j].code.substr(0,temp.size())==temp) return true;//巧妙的substr
        }
    }
    return false;
}
int main(){
    int N;
    cin>>N;
    priority_queue <int, vector<int>, greater<int> > q;//优先队列 从小到大,方便我们构造霍夫曼树 可将greater改为less,即为从大到小
    for(int i=0;i<N;i++){
        cin>>in[i].ch>>in[i].weight;
        q.push(in[i].weight);
    }
    int best=0;//计算霍夫曼的WPL
    int m=0;
    while(!q.empty()){
        int a=0;
        int b=0;
        a=q.top();
        q.pop();
        if(!q.empty()){
            b=q.top();
            q.pop();
            q.push(a+b);
        }
        m=a+b;
        best+=m;
    }
    best-=m;//m多加了一次,cut!
    // 根据霍夫曼树的构造计算weight
    int t;
    cin>>t;
    while(t--){
        int cost=0;
        for(int j=0;j<N;j++){
            cin>>ck[j].ch>>ck[j].code;
            cost+=ck[j].code.size()*in[cnt(ck[j].ch,N)].weight;
        }
        if(cost==best){
            if(frontSq(N)){//可能WPL一样,要从前缀再次判断
                printf("No\n");
            }
            else{
                printf("Yes\n");
            }
        }
        else{
            printf("No\n");
        }
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值