既然发了几篇课题b的,那也发几篇课题a的吧!
压缩算法通常用于减小数据文件的体积,其中两种常见的压缩算法是 Huffman 编码和Lempel-Ziv 算法。下面分别给出这两种算法的简单实现(使用 C++ 语言):
Huffman 编码
#include <iostream>
#include <queue>
#include <unordered_map>
#include <vector>
#include <string>
using namespace std;
struct TreeNode {
char data;
int frequency;
TreeNode* left;
TreeNode* right;
TreeNode(char d, int f) : data(d), frequency(f), left(nullptr), right(nullptr) {}
};
struct Compare {
bool operator()(TreeNode* a, TreeNode* b) {
return a->frequency > b->frequency;
}
};
unordered_map<char, string> huffmanCodes;
void generateHuffmanCodes(TreeNode* root, string code) {
if (root->left == nullptr && root->right == nullptr) {
huffmanCodes[root->data] = code;
return;
}
if (root->left != nullptr) {
generateHuffmanCodes(root->left, code + "0");
}
if (root->right != nullptr) {
generateHuffmanCodes(root->right, code + "1");
}
}
void buildHuffmanTree(string text) {
unordered_map<char, int> frequencyMap;
for (char c : text) {
frequencyMap[c]++;
}
priority_queue<TreeNode*, vector<TreeNode*>, Compare> pq;
for (auto& entry : frequencyMap) {
pq.push(new TreeNode(entry.first, entry.second));
}
while (pq.size() > 1) {
TreeNode* left = pq.top();
pq.pop();
TreeNode* right = pq.top();
pq.pop();
TreeNode* internalNode = new TreeNode('$', left->frequency + right->frequency);
internalNode->left = left;
internalNode->right = right;
pq.push(internalNode);
}
generateHuffmanCodes(pq.top(), "");
}
string compressHuffman(string text) {
buildHuffmanTree(text);
string compressedText = "";
for (char c : text) {
compressedText += huffmanCodes[c];
}
return compressedText;
}
int main() {
string text = "abracadabra";
string compressedText = compressHuffman(text);
cout << "Original text: " << text << endl;
cout << "Compressed text: " << compressedText << endl;
return 0;
}
Lempel-Ziv 算法
#include <iostream>
#include <unordered_map>
#include <vector>
using namespace std;
string compressLZ(string text) {
unordered_map<string, int> dictionary;
vector<string> result;
string current = "";
for (char c : text) {
string currentPlusC = current + c;
if (dictionary.find(currentPlusC) != dictionary.end()) {
current = currentPlusC;
} else {
result.push_back(to_string(dictionary[current]));
dictionary[currentPlusC] = dictionary.size();
current = c;
}
}
result.push_back(to_string(dictionary[current]));
string compressedText = "";
for (string code : result) {
compressedText += code + " ";
}
return compressedText;
}
int main() {
string text = "ababababcabcabc";
string compressedText = compressLZ(text);
cout << "Original text: " << text << endl;
cout << "Compressed text: " << compressedText << endl;
return 0;
}
这两个示例只是非常非常基础的实现,实际的压缩算法要复杂得多。在实际应用中,常常使用专业的库(如 zlib)或者其他高效的实现。