原题:
Description
对输入的英文大写字母序列进行统计概率,然后构建Huffman树,输出按照概率降序排序输出Huffman编码。
Input
第一行是大写字母个数n。
第二行为n个字母,中间以一个空格分隔。
Output
假设输入中共有m个不同的字母,按照出现概率降序输出,每个字母单独一行输出。
格式如下:
字母1 出现次数 Huffman编码
字母2 出现次数 Huffman编码
字母3 出现次数 Huffman编码
…
字母m 出现次数 Huffman编码
Sample Input
10
S S U U U S U L U U
Sample Output
U 6 1
S 3 01
L 1 00
思路:哈夫曼编码。自己写的代码,顺带练习了下树的一些操作,感觉写得很一般,有空再去学习下大神怎么写的。
代码:
#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
using namespace std;
struct TreeNode{
string s;//字母
string coding;//字母的编码
int count;//字母出现次数
TreeNode *left;
TreeNode *right;
};
TreeNode trNode[60];
vector<TreeNode*> v;
bool cmp1(TreeNode a, TreeNode b){
return a.count<b.count;
}
bool cmp2(TreeNode *a, TreeNode *b){
return a->count>b->count;
}
//合并两个最小的节点
TreeNode Merge_Node(TreeNode *a,TreeNode *b){
TreeNode t;
t.s=((a->s)+(b->s));
t.count=((a->count)+(b->count));
t.left=a;
t.right=b;
return t;
}
//构造哈夫曼树
void HuffmanTree(int n){
for(int i=0;i<(n-1);i++){
trNode[n+i]=Merge_Node(&trNode[2*i],&trNode[2*i+1]);
sort(trNode+2*i,trNode+i+n+1,cmp1);
}
}
//查找叶子结点,其实也是进行哈夫曼编码
void findLeafNode(TreeNode *node,string str){
if((node->left==NULL)&&node->right==NULL){
node->coding=str;
v.push_back(node);
}
else{
findLeafNode(node->left,str+"0");
findLeafNode(node->right,str+"1");
}
}
int main(){
int n;
int LetterNum=0;
char a[105];
cin>>n;
for(int i=0;i<n;i++){
cin>>a[i];
bool flag=false;
for(int j=0;j<LetterNum;j++){
if(a[i]==(trNode[j].s)[0]){
trNode[j].count++;
flag=true;
break;
}
}
if(!flag){
trNode[LetterNum].s.push_back(a[i]);
trNode[LetterNum].count=1;
trNode[LetterNum].left=NULL;
trNode[LetterNum].right=NULL;
LetterNum++;
}
}
sort(trNode,trNode+LetterNum,cmp1);
HuffmanTree(LetterNum);
findLeafNode(&trNode[2*LetterNum-2],"");
sort(v.begin(),v.end(),cmp2);
for(int i=0;i<v.size();i++)
cout<<v[i]->s<<" "<<v[i]->count<<" "<<v[i]->coding<<endl;
return 0;
}