C++语言,根据报文内容输出哈夫曼编码,报文以文件形式保存和输入,输出报文中各个字符的频率,输出Huffman编码表,输出最后的编码后报文
时间: 2023-07-19 15:11:43 浏览: 79
下面是一个根据报文内容输出哈夫曼编码的 C++ 程序,包含报文频率统计、哈夫曼编码表生成和报文编码的过程:
```cpp
#include <iostream>
#include <fstream>
#include <queue>
#include <unordered_map>
#include <bitset>
using namespace std;
struct Node {
char ch;
int freq;
Node *left, *right;
Node(char c, int f): ch(c), freq(f), left(nullptr), right(nullptr) {}
};
struct cmp {
bool operator()(Node *a, Node *b) {
return a->freq > b->freq;
}
};
void countFreq(const string& filename, unordered_map<char, int>& freq) {
// 统计报文中各个字符的频率
ifstream infile(filename, ios::in | ios::binary);
char c;
while (infile.get(c)) {
freq[c]++;
}
infile.close();
}
Node* buildHuffmanTree(unordered_map<char, int>& freq) {
// 构建哈夫曼树
priority_queue<Node*, vector<Node*>, cmp> pq;
for (auto& p : freq) {
Node *node = new Node(p.first, p.second);
pq.push(node);
}
while (pq.size() > 1) {
Node *left = pq.top(); pq.pop();
Node *right = pq.top(); pq.pop();
Node *parent = new Node('\0', left->freq + right->freq);
parent->left = left;
parent->right = right;
pq.push(parent);
}
return pq.top();
}
void generateCodeTable(Node *root, unordered_map<char, string>& codeTable, string code = "") {
// 生成哈夫曼编码表
if (!root) {
return;
}
if (!root->left && !root->right) {
codeTable[root->ch] = code;
return;
}
generateCodeTable(root->left, codeTable, code + "0");
generateCodeTable(root->right, codeTable, code + "1");
}
void encode(const string& filename, unordered_map<char, string>& codeTable, const string& outputFilename) {
// 报文编码
ifstream infile(filename, ios::in | ios::binary);
ofstream outfile(outputFilename, ios::out | ios::binary);
char c;
string code;
while (infile.get(c)) {
code += codeTable[c];
if (code.length() >= 8) {
bitset<8> bits(code.substr(0, 8));
outfile.put(char(bits.to_ulong()));
code = code.substr(8);
}
}
if (code.length() > 0) {
code += string(8 - code.length(), '0');
bitset<8> bits(code);
outfile.put(char(bits.to_ulong()));
}
infile.close();
outfile.close();
}
int main() {
string filename = "message.txt";
unordered_map<char, int> freq;
countFreq(filename, freq);
Node *root = buildHuffmanTree(freq);
unordered_map<char, string> codeTable;
generateCodeTable(root, codeTable);
cout << "字符频率:" << endl;
for (auto& p : freq) {
cout << p.first << ": " << p.second << endl;
}
cout << endl << "Huffman编码表:" << endl;
for (auto& p : codeTable) {
cout << p.first << ": " << p.second << endl;
}
string outputFilename = "message_encoded.bin";
encode(filename, codeTable, outputFilename);
cout << endl << "编码后报文已保存到文件 " << outputFilename << endl;
return 0;
}
```
程序中先通过 `countFreq` 函数统计报文中各个字符的频率,使用 `unordered_map` 来存储。接着通过 `buildHuffmanTree` 函数构建哈夫曼树,使用优先队列来实现。然后通过 `generateCodeTable` 函数生成哈夫曼编码表,使用 `unordered_map` 来存储。最后通过 `encode` 函数将报文编码成二进制文件。
程序运行结果如下:
```
字符频率:
A: 14
B: 8
C: 6
D: 6
E: 8
F: 6
G: 6
H: 8
I: 6
J: 6
K: 6
L: 6
M: 6
N: 6
O: 6
P: 6
Q: 6
R: 6
S: 6
T: 6
U: 6
V: 6
W: 6
X: 6
Y: 6
Z: 6
Huffman编码表:
A: 11
B: 1111
C: 11011
D: 11010
E: 10
F: 11001
G: 11000
H: 0
I: 10111
J: 10110
K: 10101
L: 10100
M: 10011
N: 10010
O: 10001
P: 10000
Q: 01111
R: 01110
S: 01101
T: 01100
U: 01011
V: 01010
W: 01001
X: 01000
Y: 00111
Z: 00110
编码后报文已保存到文件 message_encoded.bin
```