The question is very long and I don't know what's going on, but I understand it very well. It means to give you a string and let you output the digits occupied by common ASCII encoding and huffman encoding respectively, then output the compression ratio;
The first time I wrote the Harman encoding, I wrote it for half a day, and finally wa it several times. The output format of this compression ratio is too painful. He said that I should keep a decimal number, but if it is x.0, then, output x directly. This day, we searched for half a day and finally tried some formats before trying it out. Although the question does not require coding and decoding, I wrote it myself as I want to practice it;
The main idea is: first find the frequency (that is, the number of times) of each character, then each character occupies a node first, and then take the least two for all nodes, then, a node is constructed as the parent node of the two nodes. Its frequency is the sum of the node frequencies until only one node is left. The node is the root node, and each node is encoded, no encoding with the node, and then recursive encoding. The rule is: the encoding of the left child of a node plus '0' for the node ', the code of the right child is the code of this node + '1' until there are no left or right children;
Then, when the encoding length is obtained, for all the leaf nodes, let the encoding length multiply by the frequency, and then accumulate to get the length of all the codes.
The reference code is as follows:
[Cpp] # include <iostream>
# Include <iomanip>
# Include <cstdlib>
# Include <cstring>
# Include <queue>
# Include <cmath>
# Include <cstdio>
Using namespace std;
Struct Node
{
Int val; // record the node frequency
Char c; // The Node probability character. The c value of the intermediate node is set to 0;
Int len; // The encoding length;
Char code [31]; // encoding;
Int num; // The Position of the record in the array. It is saved for easy operation and can be left empty;
Int lchild; // If the subscript of the left child is not-1;
Int rchild; // subscript of the right child. If not, it is-1;
Int parent; // subscript of the Father's Day vertex. If not, it is-1;
};
Bool operator <(const Node & a, const Node & B) // take into account the minimum and minimum number of requests for the priority queue, and reload the number <
{
Return a. val> B. val;
}
Node a [201];
Int lens; // String Length
Int lentree; // The number of nodes;
Char s [10001]; // The read string
Int flag [10001]; // used to determine whether a character of a string has appeared before
Int pcodelen, nowcodelen; // represents the length of the object encoded with ASCII and huffman, respectively.
Double ans; // compression ratio
Void codenode (int k) // encode each node;
{
If (a [k]. lchild! =-1)
{
Strcpy (a [a [k]. lchild]. code, a [k]. code );
A [a [k]. lchild]. code [a [k]. len] = '0 ';
A [a [k]. lchild]. len = a [k]. len + 1;
Codenode (a [k]. lchild );
}
If (a [k]. rchild! =-1)
{
Strcpy (a [a [k]. rchild]. code, a [k]. code );
A [a [k]. rchild]. code [a [k]. len] = '1 ';
A [a [k]. rchild]. len = a [k]. len + 1;
Codenode (a [k]. rchild );
}
If (a [k]. lchild =-1 & a [k]. rchild =-1)
{
Nowcodelen + = a [k]. val * a [k]. len; // if it is a leaf, increase the nowcodelen value to the node encoding length value.
}
}
Void codestr (char * source, char * code) // encode the string
{
Int I;
Int j;
Int lencode = 0;
Int lensource = strlen (source );
For (I = 0; I <lensource; I ++)
{
For (j = 0; j <(lentree + 1)/2; j ++)
{
If (a [j]. c = source [I])
{
Strcpy (code + lencode, a [j]. code );
Lencode + = a [j]. len;
}
}
}
Code [lencode] = 0;
}
Void decode (char * code, char * str) // decode
{
Int I;
Int lenstr = 0;
Int lencode = strlen (code );
For (I = 0; I <lencode ;)
{
Int t = lentree-1;
While (a [t]. lchild! =-1 | a [t]. rchild! =-1)
{
If (code [I] = '0 ')
{
T = a [t]. lchild;
I ++;
}
Else
{
T = a [t]. rchild;
I ++;
}
}
Str [lenstr ++] = a [t]. c;
}
Str [lenstr] = 0;
}
Void execute ()
{
If (lentree = 1)
{
Nowcodelen = a [lentree-1]. val;
Return;
}
Int I;
Priority_queue <Node> q;
While (! Q. empty ())
Q. pop ();
For (I = 0; I <lentree; I ++)
{
A [I]. rchild = a [I]. lchild =-1;
A [I]. num = I;
Q. push (a [I]);
}
While (q. size ()! = 1) // construct the optimal binary tree
{
Node x1 = q. top ();
Q. pop ();
Node x2 = q. top ();
Q. pop ();
A [lentree]. val = x1.val + x2.val;
A [lentree]. rchild = x1.num;
A [lentree]. lchild = x2.num;
A [lentree]. num = lentree;
Q. push (a [lentree]);
Lentree ++;
}
A [lentree]. len = 0; // The encoding length of the shader root node is 0;
Nowcodelen = 0;
Codenode (lentree-1 );
/*
Char code [10001];
Codestr (s, code );
Cout <"encoding:" <endl;
Cout <code <endl;
Char str [10001];
Decode (code, str );
Cout <"decoded string:" <endl;
Cout <str <endl;
*/
}
Int main ()
{
Char c;
Char cmp [6] = {'E', 'n', 'd, '\ 0 '};
While (gets (s) & strcmp (s, cmp )! = 0)
{
Lens = strlen (s );
Lentree = 0;
Memset (flag,-1, sizeof (flag ));
Memset (a, 0, sizeof ());
For (int I = 0; I <lens; I ++) // construct all leaf nodes
{
If (flag [I]! =-1)
A [flag [I]. val ++;
Else
{
A [lentree]. c = s [I];
A [lentree]. val ++;
For (int j = I + 1; j <lens; j ++)
If (s [j] = s [I])
Flag [j] = lentree;
Lentree ++;
}
}
Pcodelen = 8 * lens; // the ASCII encoding length is the string length multiplied by 8
Execute ();
Ans = (double) pcodelen/(double) nowcodelen;
Cout <pcodelen <'';
Cout <nowcodelen <'';
If (ans-floor (ans) <0.1) // if the last digit of ans is 0, an integer is output.
Cout <ans <endl;
Else
Cout <fixed <setprecision (1) <ans <endl;
}
Return 0;
}
# Include <iostream>
# Include <iomanip>
# Include <cstdlib>
# Include <cstring>
# Include <queue>
# Include <cmath>
# Include <cstdio>
Using namespace std;
Struct Node
{
Int val; // record the node frequency
Char c; // The Node probability character. The c value of the intermediate node is set to 0;
Int len; // The encoding length;
Char code [31]; // encoding;
Int num; // The Position of the record in the array. It is saved for easy operation and can be left empty;
Int lchild; // If the subscript of the left child is not-1;
Int rchild; // subscript of the right child. If not, it is-1;
Int parent; // subscript of the Father's Day vertex. If not, it is-1;
};
Bool operator <(const Node & a, const Node & B) // take into account the minimum and minimum number of requests for the priority queue, and reload the number <
{
Return a. val> B. val;
}
Node a [201];
Int lens; // String Length
Int lentree; // The number of nodes;
Char s [10001]; // The read string
Int flag [10001]; // used to determine whether a character of a string has appeared before
Int pcodelen, nowcodelen; // represents the length of the object encoded with ASCII and huffman, respectively.
Double ans; // compression ratio
Void codenode (int k) // encode each node;
{
If (a [k]. lchild! =-1)
{
Strcpy (a [a [k]. lchild]. code, a [k]. code );
A [a [k]. lchild]. code [a [k]. len] = '0 ';
A [a [k]. lchild]. len = a [k]. len + 1;
Codenode (a [k]. lchild );
}
If (a [k]. rchild! =-1)
{
Strcpy (a [a [k]. rchild]. code, a [k]. code );
A [a [k]. rchild]. code [a [k]. len] = '1 ';
A [a [k]. rchild]. len = a [k]. len + 1;
Codenode (a [k]. rchild );
}
If (a [k]. lchild =-1 & a [k]. rchild =-1)
{
Nowcodelen + = a [k]. val * a [k]. len; // if it is a leaf, increase the nowcodelen value to the node encoding length value.
}
}
Void codestr (char * source, char * code) // encode the string
{
Int I;
Int j;
Int lencode = 0;
Int lensource = strlen (source );
For (I = 0; I <lensource; I ++)
{
For (j = 0; j <(lentree + 1)/2; j ++)
{
If (a [j]. c = source [I])
{
Strcpy (code + lencode, a [j]. code );
Lencode + = a [j]. len;
}
}
}
Code [lencode] = 0;
}
Void decode (char * code, char * str) // decode
{
Int I;
Int lenstr = 0;
Int lencode = strlen (code );
For (I = 0; I <lencode ;)
{
Int t = lentree-1;
While (a [t]. lchild! =-1 | a [t]. rchild! =-1)
{
If (code [I] = '0 ')
{
T = a [t]. lchild;
I ++;
}
Else
{
T = a [t]. rchild;
I ++;
}
}
Str [lenstr ++] = a [t]. c;
}
Str [lenstr] = 0;
}
Void execute ()
{
If (lentree = 1)
{
Nowcodelen = a [lentree-1]. val;
Return;
}
Int I;
Priority_queue <Node> q;
While (! Q. empty ())
Q. pop ();
For (I = 0; I <lentree; I ++)
{
A [I]. rchild = a [I]. lchild =-1;
A [I]. num = I;
Q. push (a [I]);
}
While (q. size ()! = 1) // construct the optimal binary tree
{
Node x1 = q. top ();
Q. pop ();
Node x2 = q. top ();
Q. pop ();
A [lentree]. val = x1.val + x2.val;
A [lentree]. rchild = x1.num;
A [lentree]. lchild = x2.num;
A [lentree]. num = lentree;
Q. push (a [lentree]);
Lentree ++;
}
A [lentree]. len = 0; // The encoding length of the shader root node is 0;
Nowcodelen = 0;
Codenode (lentree-1 );
/*
Char code [10001];
Codestr (s, code );
Cout <"encoding:" <endl;
Cout <code <endl;
Char str [10001];
Decode (code, str );
Cout <"decoded string:" <endl;
Cout <str <endl;
*/
}
Int main ()
{
Char c;
Char cmp [6] = {'E', 'n', 'd, '\ 0 '};
While (gets (s) & strcmp (s, cmp )! = 0)
{
Lens = strlen (s );
Lentree = 0;
Memset (flag,-1, sizeof (flag ));
Memset (a, 0, sizeof ());
For (int I = 0; I <lens; I ++) // construct all leaf nodes
{
If (flag [I]! =-1)
A [flag [I]. val ++;
Else
{
A [lentree]. c = s [I];
A [lentree]. val ++;
For (int j = I + 1; j <lens; j ++)
If (s [j] = s [I])
Flag [j] = lentree;
Lentree ++;
}
}
Pcodelen = 8 * lens; // the ASCII encoding length is the string length multiplied by 8
Execute ();
Ans = (double) pcodelen/(double) nowcodelen;
Cout <pcodelen <'';
Cout <nowcodelen <'';
If (ans-floor (ans) <0.1) // if the last digit of ans is 0, an integer is output.
Cout <ans <endl;
Else
Cout <fixed <setprecision (1) <ans <endl;
}
Return 0;
}