#include<iostream> #include<sstream> #include<string> #include<vector> #include<list> #include<set> #include<map> #include<stack> #include<queue> #pragma warning(disable:4996) using std::cin; using std::cout; using std::endl; using std::stringstream; using std::string; using std::vector; using std::list; using std::pair; using std::set; using std::multiset; using std::map; using std::multimap; using std::stack; using std::queue; using std::priority_queue; class Node { private: char character; int weight; int parent, lchild, rchild; string code; public: Node() { character = '\0'; weight = parent = lchild = rchild = 0; code = ""; } Node(const char &ch,const int &w) { character = ch; weight = w; parent = lchild = rchild = 0; code = ""; } Node(const int &w,const int &first,const int &second) { character = '\0'; weight = w; parent=0; lchild = std::min(first,second); rchild = std::max(first,second); code = ""; } pair<int, int>select(const vector<Node>&HfTree) { pair<int, int>children; int max_first = INT_MAX, max_second = INT_MAX; for (size_t i = 1; i !=HfTree.size(); i++) { if (HfTree[i].weight < max_first&&!HfTree[i].parent) { max_second = max_first; children.second = children.first; max_first = HfTree[i].weight; children.first = i; } else if (HfTree[i].weight < max_second&&!HfTree[i].parent) { max_second = HfTree[i].weight; children.second = i; } } return children; } map<char, string> HfCoding(const map<char, int>&char_freq) { vector<Node>HfTree(1); for (auto iter = char_freq.begin();iter!=char_freq.end();iter++) { HfTree.push_back({ iter->first,iter->second }); } for (size_t i = 0;i!=char_freq.size()-1;i++) { //找到两个权最少并且parent为0的结点 pair<int, int>children = select(HfTree); HfTree[children.first].parent = HfTree.size(); HfTree[children.second].parent = HfTree.size(); HfTree.push_back({ HfTree[children.first] .weight+ HfTree[children.second].weight,children.first,children.second}); } queue<int>Q; Q.push(HfTree.size() - 1); map<char, string>char_code; while (Q.size()) { int i = Q.front(); Q.pop(); Node parent = HfTree[i]; if (parent.character) { char_code[parent.character] = parent.code; } if (parent.lchild) { HfTree[parent.lchild].code = HfTree[i].code + '0'; Q.push(parent.lchild); } if (parent.rchild) { HfTree[parent.rchild].code = HfTree[i].code + '1'; Q.push(parent.rchild); } } return char_code; } }; int main() { //freopen("input.txt", "r", stdin); //freopen("output.txt", "w", stdout); string str; while (cin >> str) { if (str == "END") { break; } map<char, int>char_freq; for (size_t i = 0; i < str.size(); i++) { char_freq[str[i]]++; } if (char_freq.size() == 1) { cout << 8*str[0] << ' ' << 8*str[0] << ' ' << "1.0" << endl; continue; } Node HfTree; map<char,string>char_code=HfTree.HfCoding(char_freq); int length = 0; for (size_t i = 0; i < str.size(); i++) { length += char_code[str[i]].size(); } cout << 8 * str.size() << ' ' << length << ' '; printf("%.1lf\n", 8.0*(double)str.size() / (double)length); } return 0; }