C++,已知一组包含至少8个字符的数组及各字符的出现概率(随机产生)。求该字符串数组的哈夫曼编码及平均码长。(给出完整代码)
时间: 2024-10-20 15:15:56 浏览: 26
在C++中,我们可以使用优先队列(priority_queue)和哈夫曼树(Huffman Tree)的概念来计算给定字符的概率对应的哈夫曼编码。这是一个典型的动态规划问题。首先,我们需要创建一个哈夫曼节点结构体,然后按照概率构建二叉树,并生成哈夫曼编码。下面是一个简单的示例代码:
```cpp
#include <iostream>
#include <queue>
#include <vector>
#include <string>
// 定义哈夫曼节点
struct HuffmanNode {
char data;
int freq;
HuffmanNode* left = nullptr;
HuffmanNode* right = nullptr;
HuffmanNode(char ch, int f) : data(ch), freq(f) {}
};
// 计算频率总和
int totalFreq(const std::vector<HuffmanNode*>& nodes) {
int sum = 0;
for (const HuffmanNode* node : nodes)
sum += node->freq;
return sum;
}
// 插入节点到堆
void insert(HuffmanNode*& root, HuffmanNode* newNode) {
if (!root || newNode->freq < root->freq)
root = newNode;
else {
HuffmanNode* temp = root;
root = newNode;
if (newNode->freq < temp->freq)
newNode->left = temp;
else
newNode->right = temp->left;
temp->left = newNode->right;
}
}
// 构建哈夫曼树
std::pair<HuffmanNode*, HuffmanNode*> buildHuffmanTree(const std::vector<HuffmanNode*>& nodes) {
std::priority_queue<std::pair<HuffmanNode*, int>, std::vector<std::pair<HuffmanNode*, int>>, std::greater<> > pq(nodes.begin(), nodes.end());
while (pq.size() > 1) {
HuffmanNode* left = pq.top().first;
pq.pop();
HuffmanNode* right = pq.top().first;
pq.pop();
HuffmanNode* newNode = new HuffmanNode('\0', left->freq + right->freq);
newNode->left = left;
newNode->right = right;
insert(pq, newNode);
}
return pq.top();
}
// 生成哈夫曼编码
std::string getHuffmanCode(HuffmanNode* root, const std::string& prefix, std::map<char, std::string>& codes) {
if (root == nullptr) return "";
if (root->data != '\0') {
codes[root->data] = prefix;
} else {
getHuffmanCode(root->left, prefix + "0", codes);
getHuffmanCode(root->right, prefix + "1", codes);
}
return codes;
}
// 主函数
void computeHuffmanCoding(const std::vector<std::pair<char, int>>& probabilities) {
std::vector<HuffmanNode*> nodes;
for (auto prob : probabilities) {
nodes.push_back(new HuffmanNode(prob.first, prob.second));
}
// 构建哈夫曼树
auto [root, dummy] = buildHuffmanTree(nodes);
// 获取并存储哈夫曼编码
std::map<char, std::string> huffmanCodes;
getHuffmanCode(root, "", huffmanCodes);
// 计算平均码长
double averageCodeLength = 0;
for (auto& pair : huffmanCodes) {
averageCodeLength += static_cast<double>(pair.second.length()) * pair.second[0];
}
averageCodeLength /= huffmanCodes.size();
std::cout << "Huffman Codes: ";
for (const auto& code : huffmanCodes)
std::cout << code.first << ": " << code.second << ", ";
std::cout << "\nAverage Code Length: " << averageCodeLength << std::endl;
}
int main() {
// 示例数据,实际应用中需要从输入或概率数组获取
std::vector<std::pair<char, int>> probabilities = {{"a", 50}, {"b", 30}, {"c", 20}};
computeHuffmanCoding(probabilities);
return 0;
}
```
请注意,这个代码只是一个简化的版本,实际项目中可能需要处理更多的边界情况和优化。此外,上述代码假设输入的字符集不会很大,如果字符集非常大,可以考虑使用哈希表而不是直接使用`std::map`。
阅读全文