Question link:
Http://acm.hdu.edu.cn/showproblem.php? PID = 1, 1053
Explanation:
Enter a string (containing only 26 uppercase letters and '_') with 8 characters each. What are the digits of this string? If the encoding is adopted, how many digits of the string and the compression ratio (1 decimal point )?
General method:
The hash queue is used to calculate the Heman encoding of each character. The total number of digits of the string is sum (the length of each character encoding * The number of occurrences of the character ). The process of coding is as follows:
Step 1: count the number of occurrences of each character. Each character acts as a node and stores it in the priority queue based on the number of occurrences as the weight of the node.
Step 2: Combine the first two nodes in the queue into one node, update the node weights, and insert them into the priority queue.
Step 3: When only one element is left in the queue
Optimization Method:
In fact, this question only calculates the total number of digits of a string, and does not require the encoding of each character. The process of coding can be performed simultaneously with the process of finding the number of digits of a string.
Make L (t) the total number of digits of the string corresponding to T tree, and t the weight of the root node of T.
T, L (t) = sum (the length of each character encoding * The number of occurrences of each character) constructed by the number of occurrences of each character) = sum (height of each leaf * weight of the leaf ).
In step 1, each character acts as a node, or a user tree with only one node. When there is only one knot in the tree, the leaf height is 1, L (t) = T.
In step 2, two of them are taken t1 and t2 each time for merging to form a new table. T1 and t2 are left and right children of t respectively. After t1 and t2 become subtree, the height of each leaf is + 1, and the new L (T1) = weight and of each leaf in the original L (T1) + T1, according to the definition of the Harman tree, the weight of each leaf in T1 is similar to that of = T1; T2. L (t) = New L (T1) + New L (T2) = original L (T1) + t1 + original L (T2) + T2
= Original L (T1) + original L (T2) + T
To simplify programming, the priority queue only needs to store the weight t of each t
Code:
# Include <iostream> # include <iomanip> # include <queue> # include <string> using namespace STD; int main () {string s; while (CIN> S) {If (S = "end") break; int pl [27], Len; // statistical frequency memset (PL, 0, sizeof PL); Len = S. length (); For (INT I = 0; I <Len; I ++) {If (s [I] = '_') pl [0] ++; else pl [s [I]-'A' + 1] ++;} // determines whether a single character bool Yes = 0; For (INT I = 0; I <27; I ++) {If (pl [I] = Len) {cout <Len * 8 <''<Len <'' <8.0 <Endl; yes = 1; break ;} } If (yes) continue; // use the priority queue to calculate the Huffman encoding priority_queue <int, vector <int>, greater <int> q; For (INT I = 0; I <27; I ++) if (pl [I]! = 0) Q. push (pl [I]); int ans = 0, a, B; while (1) {A = Q. top (); q. pop (); If (Q. empty () break; B = Q. top (); q. pop (); ans + = a + B; q. push (a + B);} cout <Len * 8 <''<ans <''; cout <setiosflags (IOs: fixed) <setprecision (1) <(LEN * 8.0/ANS) <Endl ;}return 0 ;}
Summary:
The output method of a decimal in C ++:
#include <iomanip>cout<<setiosflags(ios::fixed)<<setprecision(1)<<ans<<endl;
How to Use priority queues in STL:
#include <queue>priority_queue<int, vector<int>, greater<int>> q;