文件压缩程序的设计与实现代码C++
时间: 2023-12-13 18:03:34 浏览: 231
以下是一个简单的文件压缩程序的设计与实现代码,使用C++语言实现:
```c++
#include <iostream>
#include <fstream>
#include <string>
#include <map>
#include <queue>
#include <bitset>
using namespace std;
// 定义字符频次类型
typedef map<char, int> FreqMap;
// 定义哈夫曼树节点类型
struct HuffmanTreeNode {
char ch;
int freq;
HuffmanTreeNode *left;
HuffmanTreeNode *right;
HuffmanTreeNode(char c, int f) : ch(c), freq(f), left(NULL), right(NULL) {}
};
// 定义哈夫曼树节点比较函数
struct HuffmanTreeNodeCompare {
bool operator() (const HuffmanTreeNode* lhs, const HuffmanTreeNode* rhs) const {
return lhs->freq > rhs->freq;
}
};
// 统计字符频次
FreqMap count_freq(const string& filename) {
FreqMap freq;
ifstream input(filename, ios::binary);
char c;
while (input.get(c)) {
freq[c]++;
}
input.close();
return freq;
}
// 构建哈夫曼树
HuffmanTreeNode* build_huffman_tree(FreqMap freq) {
priority_queue<HuffmanTreeNode*, vector<HuffmanTreeNode*>, HuffmanTreeNodeCompare> q;
for (FreqMap::iterator it = freq.begin(); it != freq.end(); it++) {
q.push(new HuffmanTreeNode(it->first, it->second));
}
while (q.size() > 1) {
HuffmanTreeNode* left = q.top();
q.pop();
HuffmanTreeNode* right = q.top();
q.pop();
HuffmanTreeNode* parent = new HuffmanTreeNode('\0', left->freq + right->freq);
parent->left = left;
parent->right = right;
q.push(parent);
}
return q.top();
}
// 生成哈夫曼编码
map<char, string> generate_huffman_codes(HuffmanTreeNode* root) {
map<char, string> codes;
if (root) {
string code;
generate_huffman_codes_helper(root, code, codes);
}
return codes;
}
void generate_huffman_codes_helper(HuffmanTreeNode* node, string& code, map<char, string>& codes) {
if (!node) {
return;
}
if (node->left == NULL && node->right == NULL) {
codes[node->ch] = code;
} else {
code.push_back('0');
generate_huffman_codes_helper(node->left, code, codes);
code.pop_back();
code.push_back('1');
generate_huffman_codes_helper(node->right, code, codes);
code.pop_back();
}
}
// 压缩文件
void compress_file(const string& filename, const map<char, string>& codes) {
ofstream output(filename + ".huff", ios::binary);
ifstream input(filename, ios::binary);
char c;
string bitstream;
while (input.get(c)) {
bitstream += codes.find(c)->second;
if (bitstream.size() >= 8) {
bitset<8> bits(bitstream.substr(0, 8));
output.put(bits.to_ulong());
bitstream.erase(0, 8);
}
}
if (!bitstream.empty()) {
bitset<8> bits(bitstream);
bits <<= (8 - bitstream.size());
output.put(bits.to_ulong());
}
input.close();
output.close();
}
// 解压缩文件
void decompress_file(const string& filename) {
ifstream input(filename, ios::binary);
string bitstream;
char c;
while (input.get(c)) {
bitset<8> bits(c);
bitstream += bits.to_string();
}
input.close();
HuffmanTreeNode* root = build_huffman_tree(count_freq(filename));
HuffmanTreeNode* node = root;
ofstream output(filename + ".dec", ios::binary);
for (string::iterator it = bitstream.begin(); it != bitstream.end(); it++) {
if (*it == '0') {
node = node->left;
} else {
node = node->right;
}
if (node->left == NULL && node->right == NULL) {
output.put(node->ch);
node = root;
}
}
output.close();
}
int main(int argc, char* argv[]) {
if (argc < 3) {
cout << "Usage: " << argv[0] << " <compress/decompress> <filename>" << endl;
return 1;
}
string mode(argv[1]);
string filename(argv[2]);
if (mode == "compress") {
FreqMap freq = count_freq(filename);
HuffmanTreeNode* root = build_huffman_tree(freq);
map<char, string> codes = generate_huffman_codes(root);
compress_file(filename, codes);
} else if (mode == "decompress") {
decompress_file(filename);
} else {
cout << "Invalid mode: " << mode << endl;
return 1;
}
return 0;
}
```
这个程序实现了文件压缩和解压缩两个功能,可以通过命令行参数指定操作模式和文件名。其中,压缩过程分为三个步骤:
1. 统计输入文件中每个字符出现的频次;
2. 基于字符频次构建哈夫曼树;
3. 生成哈夫曼编码并使用它将输入文件压缩成二进制文件。
解压缩过程分为两个步骤:
1. 读取输入文件的二进制数据流;
2. 使用哈夫曼编码将二进制数据流解压成原始文件。
注意,这个实现中使用了C++标准库中的STL容器和算法,可以通过调用STL函数来简化代码并提高效率。
阅读全文