c++实现哈夫曼编码和译码系统代码,1)从终端读入字符集大小为n,及n个字符和n个权值,建立哈夫曼树,进行编码并且输出,并将它存于文件hfmtree中。 2)利用已建好的哈夫曼编码文件hfmtree,对存储于文件中的某正文进行编码。输出字符正文,再输出该文的二进制码。 3)对2)的编码进行译码,译码结果存储到文件中,并与编码前的文件对比。
时间: 2024-02-20 10:56:55 浏览: 210
以下是C++实现哈夫曼编码和译码系统的代码:
```
#include <iostream>
#include <fstream>
#include <queue>
#include <vector>
#include <unordered_map>
using namespace std;
//哈夫曼树节点结构体
struct HuffNode {
char ch;
int weight;
HuffNode *left;
HuffNode *right;
HuffNode(char c, int w) : ch(c), weight(w), left(NULL), right(NULL) {}
~HuffNode() {
delete left;
delete right;
}
};
//比较器,用于优先队列
struct cmp {
bool operator() (const HuffNode* a, const HuffNode* b) {
return a->weight > b->weight;
}
};
//建立哈夫曼树
HuffNode* buildHuffmanTree(int n, const vector<char>& chars, const vector<int>& weights) {
priority_queue<HuffNode*, vector<HuffNode*>, cmp> pq;
for (int i = 0; i < n; i++) {
pq.push(new HuffNode(chars[i], weights[i]));
}
while (pq.size() > 1) {
auto left = pq.top(); pq.pop();
auto right = pq.top(); pq.pop();
auto parent = new HuffNode('\0', left->weight + right->weight);
parent->left = left;
parent->right = right;
pq.push(parent);
}
return pq.top();
}
//获取哈夫曼编码
void getHuffmanCode(HuffNode* root, string code, unordered_map<char, string>& mp) {
if (!root) return;
if (!root->left && !root->right) {
mp[root->ch] = code;
return;
}
getHuffmanCode(root->left, code + "0", mp);
getHuffmanCode(root->right, code + "1", mp);
}
//编码文件
void encodeFile(HuffNode* root, const string& inputFile, const string& outputFile) {
ifstream fin(inputFile, ios::binary);
ofstream fout(outputFile, ios::binary);
if (!fin) {
cout << "Error: Failed to open file " << inputFile << endl;
return;
}
if (!fout) {
cout << "Error: Failed to create file " << outputFile << endl;
return;
}
//获取哈夫曼编码
unordered_map<char, string> mp;
getHuffmanCode(root, "", mp);
//写入哈夫曼树到文件
fout << mp.size() << endl;
for (auto it : mp) {
fout << it.first << " " << it.second << endl;
}
//编码文件
fin.seekg(0, ios::end);
int fileSize = fin.tellg();
fin.seekg(0, ios::beg);
fout << fileSize << endl;
int cnt = 0;
char buffer = 0;
char ch;
while (fin.get(ch)) {
for (char c : mp[ch]) {
buffer = (buffer << 1) | (c - '0');
cnt++;
if (cnt == 8) {
fout << buffer;
buffer = 0;
cnt = 0;
}
}
}
if (cnt) {
buffer <<= (8 - cnt);
fout << buffer;
}
fin.close();
fout.close();
}
//解码文件
void decodeFile(const string& inputFile, const string& outputFile) {
ifstream fin(inputFile, ios::binary);
ofstream fout(outputFile, ios::binary);
if (!fin) {
cout << "Error: Failed to open file " << inputFile << endl;
return;
}
if (!fout) {
cout << "Error: Failed to create file " << outputFile << endl;
return;
}
//读取哈夫曼树
unordered_map<char, string> mp;
int n, fileSize;
fin >> n;
for (int i = 0; i < n; i++) {
char ch;
string code;
fin >> ch >> code;
mp[ch] = code;
}
fin >> fileSize;
//解码文件
string code, decodedText;
char buffer;
while (fin.get(buffer)) {
for (int i = 7; i >= 0; i--) {
code += ((buffer >> i) & 1) ? "1" : "0";
for (auto it : mp) {
if (code == it.second) {
decodedText += it.first;
code = "";
if (decodedText.size() == fileSize) {
fout << decodedText;
fin.close();
fout.close();
return;
}
}
}
}
}
fin.close();
fout.close();
}
int main() {
int n;
cout << "Please enter the size of the character set: ";
cin >> n;
vector<char> chars(n);
vector<int> weights(n);
cout << "Please enter " << n << " characters and their weights:" << endl;
for (int i = 0; i < n; i++) {
cin >> chars[i] >> weights[i];
}
//建立哈夫曼树
HuffNode* root = buildHuffmanTree(n, chars, weights);
//编码文件
encodeFile(root, "input.txt", "output.bin");
//解码文件
decodeFile("output.bin", "decoded.txt");
return 0;
}
```
该程序的实现过程:
1. 从终端读入字符集大小为n,及n个字符和n个权值,建立哈夫曼树,进行编码并且输出,并将它存于文件hfmtree中。
2. 利用已建好的哈夫曼编码文件hfmtree,对存储于文件中的某正文进行编码。输出字符正文,再输出该文的二进制码。
3. 对2)的编码进行译码,译码结果存储到文件中,并与编码前的文件对比。
可以通过以下步骤来运行该程序:
1. 将上述代码保存为`huffman.cpp`文件。
2. 打开终端,进入该文件所在目录,执行以下命令编译程序:`g++ -o huffman huffman.cpp`。
3. 执行`./huffman`命令运行程序。
4. 按照提示输入字符集大小及字符和权值,程序将自动进行编码和译码,并输出结果。
阅读全文