题目描述
给定一只含有小写字母的字符串;输出其哈夫曼编码的长度
输入
第一行一个整数T,代表样例的个数,接下来T行,每行一个字符串,0<T<=2000,字符串长度0<L<=1500.
输出
对于每个字符串,输出其哈夫曼编码长度
样例输入
<span style="color:#333333">3
hrvsh
lcxeasexdphiopd
mntflolfbtbpplahqolqykrqdnwdoq
</span>
样例输出
<span style="color:#333333">10
51
115
</span>
提示
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
typedef long long ll;
const int INF=0x3f3f3f;
priority_queue<int,vector<int>,greater<int>>q;
int b[30];
void solve()
{
while(!q.empty())
q.pop();
for(int i=0;i<26;i++)
{
if(b[i])
q.push(b[i]);
}
ll ans=0;
while(q.size()>1)
{
int a=q.top();
q.pop();
int b=q.top();
q.pop();
int c=a+b;
q.push(c);
ans+=c;
}
cout<<ans<<endl;
}
int main()
{
int T;
cin>>T;
while(T--)
{
string s;
cin>>s;
int len=s.size();
memset(b,0,sizeof(b));
for(int i=0;i<len;i++)
{
b[s[i]-'a']++;
}
solve();
}
return 0;
}
借助优先级队列greater从小到大排列,大根堆来构建哈夫曼树
priority_queue<
int
,vector<
int
>,greater<
int
>>q;
哈夫曼编码
记录每个字母出现的次数,按照字母的出现次数来构建哈夫曼树
for
(
int
i=0;i<len;i++)
{
b[s[i]-
'a'
]++;
}
利用q来构建哈夫曼树
while
(!q.empty())//清空q
q.pop();
for
(
int
i=0;i<26;i++)
{
if
(b[i])
q.push(b[i]);
}
ll ans=0;
while
(q.size()>1)//构建哈夫曼树
{
int
a=q.top();
q.pop();
int
b=q.top();
q.pop();
int
c=a+b;
q.push(c);
ans+=c;
}
有参考