霍夫曼编码
霍夫曼编码
英文名 Huffman Coding
中文名:霍夫曼、赫夫曼、哈夫曼
具体原理不重述,见百科
维基百科:http://zh.wikipedia.org/zh/%E9%9C%8D%E5%A4%AB%E6%9B%BC%E7%BC%96%E7%A0%81
百度百科:http://baike.baidu.com/view/189694.htm
几个点:
树节点的表示
霍夫曼树的建立
得到编码映射
编码
解码,根据霍夫曼树解码
演示 I
A 1 B 2 C 3 D 4 E 5
^Z
A 010
B 011
C 00
D 10
E 11
Encoding:
A
B
C
D
E
^Z
010011001011
Decoding:
010011001011
ABCDE
演示 II
asdf 23 asdfwoeri 232 ljljkl 2398 agslk;jfqwoeijasldfjals 988
^Z
agslk;jfqwoeijasldfjals 01
asdf 000
asdfwoeri 001
ljljkl 1
Encoding:
asdf
^Z
000
Decoding:
010000011111111
agslk;jfqwoeijasldfjalsasdfasdfwoeriljljklljljklljljklljljklljljklljljklljljkl
实现:
1
#include
<
iostream
>
2 #include < string >
3 #include < algorithm >
4 #include < vector >
5 #include < map >
6 using namespace std;
7
8 struct node
9 {
10 string trueform;
11 double probability;
12 string encoding;
13 node * left;
14 node * right;
15 node( string tt = "" , double tp = 0.0 , string te = "" , node * tl = 0 , node * tr = 0 )
16 : trueform(tt), probability(tp), encoding(te), left(tl), right(tr) {}
17 friend bool operator < ( const node & lhs, const node & rhs);
18 friend bool operator == ( const node & lhs, const node & rhs);
19 };
20
21 bool operator < ( const node & lhs, const node & rhs)
22 {
23 return lhs.probability < rhs.probability;
24 }
25
26 bool operator == ( const node & lhs, const node & rhs)
27 {
28 return lhs.probability == rhs.probability;
29 }
30
31 void init(vector < node >& treenodes)
32 {
33 treenodes.clear();
34 string tt;
35 double tp;
36 while (cin >> tt >> tp)
37 {
38 treenodes.push_back(node(tt, tp));
39 }
40 sort(treenodes.begin(), treenodes.end());
41 }
42
43 void generateTree(node *& htree, vector < node >& treenodes)
44 {
45 while (treenodes.size() >= 2 )
46 {
47 node * left = new node(treenodes[ 0 ]);
48 node * right = new node(treenodes[ 1 ]);
49 treenodes.erase(treenodes.begin(), treenodes.begin() + 2 );
50 node temp( "" , left -> probability + right -> probability, "" , left, right);
51 treenodes.push_back(temp);
52 sort(treenodes.begin(), treenodes.end());
53 }
54 htree = new node(treenodes[ 0 ]);
55 }
56
57 void generateCoding(map < string , string >& encodingmap, node * htree, string coding = "" )
58 {
59 if (htree != 0 )
60 {
61 if (htree -> left != 0 )
62 {
63 generateCoding(encodingmap, htree -> left, coding + ' 0 ' );
64 }
65 if (htree -> right != 0 )
66 {
67 generateCoding(encodingmap, htree -> right, coding + ' 1 ' );
68 }
69 if (htree -> left == 0 && htree -> right == 0 )
70 {
71 encodingmap[htree -> trueform] = coding;
72 htree -> encoding = coding;
73 // codingnodes.push_back(node(htree->trueform, htree->probability, coding, htree->left, htree->right));
74 }
75 }
76 }
77
78 void inputCiphertext( string & ciphertext)
79 {
80 cin.clear();
81 cin >> ciphertext;
82 // for (string::size_type i = 0; i != ciphertext.size(); ++i)
83 // {
84 // if (ciphertext[i] != '0' && ciphertext[i] != '1')
85 // {
86 // cerr << "Ciphertext error!" << endl;
87 // exit(1);
88 // }
89 // }
90 }
91
92 string decodeCiphertext( string & result, const string & ciphertext, node * htree)
93 {
94 result.clear();
95 node * temp;
96 for ( string ::size_type i = 0 ; i != ciphertext.size();)
97 {
98 temp = htree;
99 while (temp -> left != 0 && i != ciphertext.size())
100 {
101 if (ciphertext[i] == ' 0 ' )
102 {
103 temp = temp -> left;
104 }
105 else if (ciphertext[i] == ' 1 ' )
106 {
107 temp = temp -> right;
108 }
109 else
110 {
111 cerr << " Illegal character! " << endl;
112 exit( 1 );
113 }
114 ++ i;
115 }
116 result += temp -> trueform;
117 }
118
119 if (temp -> left != 0 )
120 {
121 cerr << " Ciphertext cannot be decoded! " << endl;
122 }
123 return result;
124 }
125
126 void inputPlaintext(vector < string >& plaintext)
127 {
128 cin.clear();
129 string temp;
130 while (cin >> temp)
131 {
132 plaintext.push_back(temp);
133 }
134 }
135
136 string encodePlaintext( string & result, const vector < string >& plaintext, map < string , string >& encodingmap)
137 {
138 result.clear();
139 for (vector < string > ::const_iterator cit = plaintext.begin(); cit != plaintext.end(); ++ cit)
140 {
141 if (encodingmap.find( * cit) != encodingmap.end())
142 {
143 // const map<string, string>& encodingmap
144 // result += encodingmap[*cit];
145 result += encodingmap[ * cit];
146 }
147 else
148 {
149 cerr << " Cannot encode! " << endl;
150 }
151 }
152 return result;
153 }
154
155 int main()
156 {
157 vector < node > treenodes;
158 init(treenodes);
159 node * htree = 0 ;
160 generateTree(htree, treenodes);
161 // for (vector<node>::size_type i = 0; i != treenodes.size(); ++i)
162 // {
163 // cout << treenodes[i].trueform << '\t' << treenodes[i].probability << endl;
164 // }
165 map < string , string > encodingmap;
166 generateCoding(encodingmap, htree);
167 for (map < string , string > ::const_iterator cit = encodingmap.begin(); cit != encodingmap.end(); ++ cit)
168 {
169 cout << cit -> first << ' \t ' << cit -> second << endl;
170 }
171 cout << " Encoding: " << endl;
172 vector < string > plaintext;
173 inputPlaintext(plaintext);
174 string encoderesult;
175 encodePlaintext(encoderesult, plaintext, encodingmap);
176 cout << encoderesult << endl;
177
178 cout << " Decoding: " << endl;
179 string ciphertext;
180 inputCiphertext(ciphertext);
181 string result;
182 decodeCiphertext(result, ciphertext, htree);
183 cout << result << endl;
184 }
2 #include < string >
3 #include < algorithm >
4 #include < vector >
5 #include < map >
6 using namespace std;
7
8 struct node
9 {
10 string trueform;
11 double probability;
12 string encoding;
13 node * left;
14 node * right;
15 node( string tt = "" , double tp = 0.0 , string te = "" , node * tl = 0 , node * tr = 0 )
16 : trueform(tt), probability(tp), encoding(te), left(tl), right(tr) {}
17 friend bool operator < ( const node & lhs, const node & rhs);
18 friend bool operator == ( const node & lhs, const node & rhs);
19 };
20
21 bool operator < ( const node & lhs, const node & rhs)
22 {
23 return lhs.probability < rhs.probability;
24 }
25
26 bool operator == ( const node & lhs, const node & rhs)
27 {
28 return lhs.probability == rhs.probability;
29 }
30
31 void init(vector < node >& treenodes)
32 {
33 treenodes.clear();
34 string tt;
35 double tp;
36 while (cin >> tt >> tp)
37 {
38 treenodes.push_back(node(tt, tp));
39 }
40 sort(treenodes.begin(), treenodes.end());
41 }
42
43 void generateTree(node *& htree, vector < node >& treenodes)
44 {
45 while (treenodes.size() >= 2 )
46 {
47 node * left = new node(treenodes[ 0 ]);
48 node * right = new node(treenodes[ 1 ]);
49 treenodes.erase(treenodes.begin(), treenodes.begin() + 2 );
50 node temp( "" , left -> probability + right -> probability, "" , left, right);
51 treenodes.push_back(temp);
52 sort(treenodes.begin(), treenodes.end());
53 }
54 htree = new node(treenodes[ 0 ]);
55 }
56
57 void generateCoding(map < string , string >& encodingmap, node * htree, string coding = "" )
58 {
59 if (htree != 0 )
60 {
61 if (htree -> left != 0 )
62 {
63 generateCoding(encodingmap, htree -> left, coding + ' 0 ' );
64 }
65 if (htree -> right != 0 )
66 {
67 generateCoding(encodingmap, htree -> right, coding + ' 1 ' );
68 }
69 if (htree -> left == 0 && htree -> right == 0 )
70 {
71 encodingmap[htree -> trueform] = coding;
72 htree -> encoding = coding;
73 // codingnodes.push_back(node(htree->trueform, htree->probability, coding, htree->left, htree->right));
74 }
75 }
76 }
77
78 void inputCiphertext( string & ciphertext)
79 {
80 cin.clear();
81 cin >> ciphertext;
82 // for (string::size_type i = 0; i != ciphertext.size(); ++i)
83 // {
84 // if (ciphertext[i] != '0' && ciphertext[i] != '1')
85 // {
86 // cerr << "Ciphertext error!" << endl;
87 // exit(1);
88 // }
89 // }
90 }
91
92 string decodeCiphertext( string & result, const string & ciphertext, node * htree)
93 {
94 result.clear();
95 node * temp;
96 for ( string ::size_type i = 0 ; i != ciphertext.size();)
97 {
98 temp = htree;
99 while (temp -> left != 0 && i != ciphertext.size())
100 {
101 if (ciphertext[i] == ' 0 ' )
102 {
103 temp = temp -> left;
104 }
105 else if (ciphertext[i] == ' 1 ' )
106 {
107 temp = temp -> right;
108 }
109 else
110 {
111 cerr << " Illegal character! " << endl;
112 exit( 1 );
113 }
114 ++ i;
115 }
116 result += temp -> trueform;
117 }
118
119 if (temp -> left != 0 )
120 {
121 cerr << " Ciphertext cannot be decoded! " << endl;
122 }
123 return result;
124 }
125
126 void inputPlaintext(vector < string >& plaintext)
127 {
128 cin.clear();
129 string temp;
130 while (cin >> temp)
131 {
132 plaintext.push_back(temp);
133 }
134 }
135
136 string encodePlaintext( string & result, const vector < string >& plaintext, map < string , string >& encodingmap)
137 {
138 result.clear();
139 for (vector < string > ::const_iterator cit = plaintext.begin(); cit != plaintext.end(); ++ cit)
140 {
141 if (encodingmap.find( * cit) != encodingmap.end())
142 {
143 // const map<string, string>& encodingmap
144 // result += encodingmap[*cit];
145 result += encodingmap[ * cit];
146 }
147 else
148 {
149 cerr << " Cannot encode! " << endl;
150 }
151 }
152 return result;
153 }
154
155 int main()
156 {
157 vector < node > treenodes;
158 init(treenodes);
159 node * htree = 0 ;
160 generateTree(htree, treenodes);
161 // for (vector<node>::size_type i = 0; i != treenodes.size(); ++i)
162 // {
163 // cout << treenodes[i].trueform << '\t' << treenodes[i].probability << endl;
164 // }
165 map < string , string > encodingmap;
166 generateCoding(encodingmap, htree);
167 for (map < string , string > ::const_iterator cit = encodingmap.begin(); cit != encodingmap.end(); ++ cit)
168 {
169 cout << cit -> first << ' \t ' << cit -> second << endl;
170 }
171 cout << " Encoding: " << endl;
172 vector < string > plaintext;
173 inputPlaintext(plaintext);
174 string encoderesult;
175 encodePlaintext(encoderesult, plaintext, encodingmap);
176 cout << encoderesult << endl;
177
178 cout << " Decoding: " << endl;
179 string ciphertext;
180 inputCiphertext(ciphertext);
181 string result;
182 decodeCiphertext(result, ciphertext, htree);
183 cout << result << endl;
184 }