您的位置:首页 > 其它

problemJ

2016-04-10 22:19 162 查看
简单题意:求输入字符串的霍夫曼编码的效率

解题思路:把给每个字符在字符串中出现的次数作为该字符的权值,然后建立二叉树存储该字符,权值越小,在二叉树中的深度越深,权值越大,在二叉树中的深度越浅。

每次选择所有字符串队列中权值最小的两个字符,然后建立一个新节点,将这两字符节点连接起来,新节点的权值为这两个字符节点的权值之和。

然后将新节点加入原队列中,再迭代进行上述操作,直到最后建成一棵树,即只剩一个节点。因为每次从队列中选择权值最小的节点,故采用优先队列比较合适。

得到的这棵树中,所有字符节点都在叶节点上,用叶节点的权值乘以该叶节点的深度(根节点的深度为0),即为该霍夫曼编码的编码长度

感想:这题和ProblemD 是一样的 
AC代码:#include <iostream>

#include <cstring

>#include <string>using namespace std;

struct{ int weight; int parent; int left; int right; }node[60];

int main()

{ char ch[100000];

 int hash[35];

 int i,j,k; int len;

 while(cin>>ch,strcmp(ch,"END")!=0)

{ memset(hash,0,sizeof(hash));

 len=strlen(ch);

 for(i=0;i<len;i++)

 { hash[ch[i]-64]++; }

 for(i=1,j=1;i<35;i++)

 { if(hash[i]!=0)

{ node[j].weight=hash[i];

 node[j].parent=node[j].left=node[j].right=0;

 j++; } }

j--;

for(i=j+1;i<j*2;i++)

 node[i].parent=node[i].left=node[i].right=0;

 for(i=j+1;i<j*2;i++)

 { int m1,m2; m1=m2=999999;

int x1,x2;

for(k=1;k<i;k++)

{ if(node[k].weight<m1&&node[k].parent==0)

 { m2=m1; x2=x1; m1=node[k].weight; x1=k;

} else if

(node[k].weight<m2&&node[k].parent==0)

 { m2=node[k].weight; x2=k; } } node[i].weight=m1+m2;

node[i].right=x1;

node[i].left=x2;

node[x1].parent=i;

 node[x2].parent=i; }

 int sum=0; int cnt;

for(i=1;i<j+1;i++)

 { k=i; cnt=0;

while(node[k].parent!=0)

 { k=node[k].parent; cnt++; }

 sum+=cnt*node[i].weight; } if(j==1) sum=len;

float ratio;

 ratio=float(len*8)/sum;

printf("%d %d %.1f\n",len*8,sum,ratio); }

return 0;}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: