////////////////////////////////////////////////////////////////////////////////////////
//2352935 2010-11-18 15:33:40 Accepted 1117 C 0 160 VRS
//1117 哈夫曼树
//注意Build_HuffmanTree()这个函数只支持至少两个Node来生成haffman的,所以只有一位时要特殊处理
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct _hufnode
{
int weight;
int level;
int parent;
int lchild;
int rchild;
}hufnode;
hufnode *Node;
int charFreq[30][2];
int Build_HuffmanTree(int n)
{
int i,j;
int maxnum;
int min1,min2,pos1,pos2;
maxnum=2*n-1;
for(i=0;i<n;i++)
{
Node[i].weight=charFreq[i][1];
Node[i].parent=-1;
Node[i].level=0;
Node[i].lchild=-1;
Node[i].rchild=-1;
}
pos1=0;
for(j=0;j<n-1;j++)
{
min1=min2=10000;
for(i=0;i<n+j;i++)
{
if(Node[i].parent==-1 && min1>Node[i].weight)
{
min2=min1;
pos2=pos1;
min1=Node[i].weight;
pos1=i;
}
else if(Node[i].parent==-1 && min2>Node[i].weight)
{
min2=Node[i].weight;
pos2=i;
}
}
Node[n+j].lchild=pos1;
Node[n+j].rchild=pos2;
Node[n+j].weight=Node[pos1].weight+Node[pos2].weight;
Node[n+j].parent=-1;
Node[pos1].parent=n+j;
Node[pos2].parent=n+j;
}
return maxnum-1;
}
void BuildLevel(int root,int level)
{
if(Node[root].lchild==-1 && Node[root].rchild==-1)
Node[root].level=level;
else if(Node[root].lchild==-1)
BuildLevel(Node[root].rchild,level+1);
else if(Node[root].rchild==-1)
BuildLevel(Node[root].lchild,level+1);
else
{
BuildLevel(Node[root].lchild,level+1);
BuildLevel(Node[root].rchild,level+1);
}
}
int main()
{
char inputString[10000];
int charNum[30];
Node=(hufnode*)calloc(60,sizeof(hufnode));
int len,root;
int i,j;
int result;
while(scanf("%s",&inputString) && strcmp(inputString,"END\0"))
{
memset(charNum,0,sizeof(charNum));
len=strlen(inputString);
for(i=0;i<len;i++)
{
if(inputString[i]=='_')
charNum[26]++;
else
charNum[inputString[i]-'A']++;
}
j=0;
for(i=0;i<=26;i++)
{
if(charNum[i]>0)
{
charFreq[j][0]=i;
charFreq[j++][1]=charNum[i];
}
}
if(j==1)
{
printf( "%d %d 8.0\n" , 8*len , len);
continue;
}
root=Build_HuffmanTree(j);
BuildLevel(root,0);
result=0;
for(i=0;i<j;i++)
result+=charFreq[i][1]*Node[i].level;
printf("%d %d %.1f\n",len*8,result,(float)len*8/result);
}
free(Node);
return 0;
}