1 #include <stdio.h>
2 #include <queue>
3 #include <iostream>
4 using namespace std;
5 struct Node {
6 int f;
7 // int height;
8 int parent;
9 bool visited;
10 }node[100];
11
12 int num, r;
13 void getSmallestTwo (int &t1, int &t2){
14 int i, min = 99999999;
15 for (i = 0; i < num+r; i++) {
16 if (!node[i].visited && node[i].f < min) {
17 min = node[i].f;
18 t1 = i;
19 }
20 }
21 min = 99999999;
22 for (i = 0; i < num+r; i++) {
23 if (!node[i].visited && node[i].f < min && i != t1) {
24 min = node[i].f;
25 t2 = i;
26 }
27 }
28 }
29
30 int getHeight(int x) {
31 int i = x, height = 0;
32 while(node[i].parent != -1) {
33 height++;
34 i = node[i].parent;
35 }
36 return height;
37 }
38 int main() {
39 string str;
40 int i, oribit, nowbit;
41 double ratio;
42 while (cin>>str && str != "END") {
43 int a[27] = {0};
44 oribit = 8 * str.size();
45 nowbit = 0;
46 for (i = 0; i < 100; i++) {
47 node[i].f = 0;
48 node[i].visited = 0;
49 // node[i].height = 0;
50 node[i].parent = -1;
51 }
52 for (i = 0; i < str.size(); i++) {
53 if (str[i] == '_') {
54 a[26]++;
55 } else {
56 a[str[i]-65]++;
57 }
58 }
59 int j = 0;
60 for (i = 0; i < 27; i++) {
61 if (a[i])
62 node[j++].f = a[i];
63 }
64 num = j;
65 // cout << num << endl;
66 if (num > 1) {
67 for ( r = 0; r < num-1; r++) { //n-1轮即可构建赫夫曼编码树
68 int t1, t2;
69 getSmallestTwo(t1, t2);
70 node[t1].visited = 1; //标记为遍历过,相当于从队列中删掉,避免重新比较
71 node[t2].visited = 1;
72 node[t1].parent = num + r; //不断增加节点数
73 node[t2].parent = num + r;
74 node[num+r].f = node[t1].f + node[t2].f;
75 }
76 for (i = 0; i < num; i++) {
77 int height = getHeight(i); //获取节点高度
78 // cout << height << endl;
79 nowbit += node[i].f * height; //加上每个几点的高度和频数乘积
80 }
81 } else {
82 nowbit = str.size();;
83 }
84 fdsc
85 ratio = (double)oribit / nowbit;
86 printf("%d %d %.1lf\n", oribit, nowbit, ratio);
87 }
88 return 0;
89 }