先给出8个字母 [a, b, c,d, e, f, g, h},它们出现的概率分别为[ 0.07, 0.19, 0.02, 0.06,0.32,0.03,0.21,0.10},组成字符。串为:abcdfhgedecf,请设计哈夫曼编码并输出编码后二进制码。C++
时间: 2024-10-23 07:19:58 浏览: 27
首先,为了设计哈夫曼编码,我们需要按照字符出现概率从低到高构建一颗二叉树,即每个小概率的字符作为叶子节点,合并概率较大的两个节点形成新的内部节点,直到所有字符都变成根节点。这是一个典型的动态规划问题。
以下是步骤:
1. 将给定的概率数组和字符数组转换成结构体或元组列表,以便于操作。
2. 创建一个优先队列,用于存储构建过程中生成的二叉树节点,初始时每个叶子节点包含字符和对应的概率。
3. 选取概率最低的两个节点,将它们合并为一个新的节点,并更新其概率为两节点之和。新节点添加到优先队列中。
4. 重复此过程,直至只剩下一个节点,这个就是哈夫曼树的根节点。
5. 从根节点开始遍历哈夫曼树,对于每个字符记录下到达该节点的路径,路径表示的就是该字符的编码。路径用二进制表示,从左往右,遇到的是0则走左分支,遇到的是1则走右分支。
下面是简化的C++代码实现:
```cpp
#include <queue>
#include <vector>
struct Node {
char data;
double freq;
int left, right;
};
Node merge(Node a, Node b) {
Node newNode;
newNode.data = '\0';
newNode.freq = a.freq + b.freq;
newNode.left = a.left, newNode.right = b.right;
if (a.freq > b.freq)
newNode.left = a, newNode.right = b;
else
newNode.left = b, newNode.right = a;
return newNode;
}
std::string huffmanEncoding(const std::vector<std::pair<char, double>>& probabilities) {
std::priority_queue<Node, std::vector<Node>, std::greater<Node>> pq;
for (auto& pair : probabilities) {
Node node;
node.data = pair.first;
node.freq = pair.second;
node.left = node.right = -1;
pq.push(node);
}
while (pq.size() > 1) {
Node left = pq.top(); pq.pop();
Node right = pq.top(); pq.pop();
pq.push(merge(left, right));
}
Node root = pq.top();
std::string encoding;
dfs(root, "", encoding);
return encoding;
}
void dfs(Node node, std::string code, std::string& encoding) {
if (node.data != '\0') {
encoding += '0' + (code == "" ? "0" : code[node.left]); // 0代表左分支,1代表右分支
}
if (node.left != -1)
dfs(node.left, '1' + code, encoding); // 右子节点编码前加1
if (node.right != -1)
dfs(node.right, code, encoding); // 左子节点不需要编码前缀
}
// 示例:
int main() {
std::vector<std::pair<char, double>> probabilities = {{'a', 0.07}, {'b', 0.19}, {'c', 0.02}, {'d', 0.06}, {'e', 0.32}, {'f', 0.03}, {'g', 0.21}, {'h', 0.10}};
auto encodedChars = huffmanEncoding(probabilities);
// 输出编码后的二进制字符串
for (char ch : encodedChars)
std::cout << std::bitset<8>(ch);
return 0;
}
```
注意:由于哈夫曼树的构造是递归的,上述代码未处理空格和边界情况,实际应用需要做适当的调整。在运行上面的代码之前,先确保输入的字符集合和概率数组是正确的。
阅读全文