求hufman编码

偷懒的写法,输入是随便一串字符串,比如“aaaaabsdfkhsdaa”,依次求字母出现概率,然后计算编码。

/***********************************************\
 |Author: Messyidea
 |Created Time: 2014-5-9 18:54:25
 |File Name: hufman.cpp
 |Description: 
\***********************************************/
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <string>
#include <cstring>
#include <algorithm>
#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>

using namespace std;
struct node{
    string c;
    double p;       //possibility
    bool operator < (node a)const{
        return p>a.p;
    }
};
priority_queue<node> pq;
map<string,int> ma;
map<string,string> mb;
int main() {
    freopen("input2.txt","r",stdin); 
    string s;
    cin>>s;
    //cout<<s<<endl;
    int total = s.length();
    for(int i = 0;i<total;++i){     //计算每个字符出现的次数 
        //cout<<s[i]<<endl;
        string ss = "";
        ss += s[i];
        ma[ss] ++;
    }
    map <string,int>::iterator it = ma.begin();
    while(it!=ma.end()){            //计算每个字符出现的概率 
        node tp;
        tp.c = it->first;
        tp.p = (it->second)*1.0/total;
        //cout<<tp.c<<"  "<<tp.p<<endl;
        pq.push(tp);
        it++;
    }
    while(pq.size()>=2){        //编码 
        node t1,t2,t3;
        t1 = pq.top();
        pq.pop();
        t2 = pq.top();
        pq.pop();
        //cout<<t1.p<<" "<<t2.p<<endl;
        t3.c = t1.c + t2.c;
        for(int i=0;i<t1.c.length();++i){
            string ss = "";
            ss += t1.c[i];
            mb[ss] += "0";
            //cout<<ss<<endl;
        }
        for(int i=0;i<t2.c.length();++i){
            string ss = "";
            ss += t2.c[i];
            mb[ss] += "1";
        }
        t3.p = t1.p + t2.p;
        pq.push(t3);
    }
    map<string,string>::iterator it2 = mb.begin();
    while(it2!=mb.end()){               //逆序并输出 
        reverse((it2->second).begin(),(it2->second).end());
        cout<<it2->first<<" "<<it2->second<<endl;
        it2++;
    }

    
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值