前言:电信专业萌新一枚,也是借鉴了ai和其他文章实现如下题目要求,亲试vs可以跑出来,第一次发布文章分享给大家,哪里做的不好希望大家指出来轻喷,觉得有用就点个赞,谢谢!
题目:根据字符使用频率(权值)生成一棵唯一的哈夫曼编码树。输入的第一行是整数n,表示字符集有n个字符。接下来n行,每行是一个字符及其使用频率(权重)。字符都是英文字母。再接下来是若干行,有的是字母串,有的是哈夫曼编码串。输出是对输入中的字母串,输出该字符串的编码,对输入中的哈夫曼编码串,将其解码,输出原始字符串。
样例输入 3
g 4
d 8
c 10
dc
样例输出 110
代码实现:
#include <iostream>
#include <queue>
#include <unordered_map>
#include <vector>
using namespace std;
// 哈夫曼树节点结构
struct Node {
char data;
int freq;
Node *left, *right;
Node(char data, int freq) : data(data), freq(freq), left(nullptr), right(nullptr) {}
~Node() {
delete left;
delete right;
}
};
// 优先队列中的比较函数,用于构建哈夫曼树时按照频率从小到大排序
struct Compare {
bool operator()(Node* a, Node* b) {
return a->freq > b->freq;
}
};
// 构建哈夫曼树的函数
Node* buildHuffmanTree(priority_queue<Node*, vector<Node*>, Compare>& pq) {
while (pq.size() > 1) {
Node* left = pq.top();
pq.pop();
Node* right = pq.top();
pq.pop();
Node* parent = new Node('$', left->freq + right->freq);
parent->left = left;
parent->right = right;
pq.push(parent);
}
return pq.top();
}
// 递归生成哈夫曼编码并存储在哈希表中
void generateCodes(Node* root, string code, unordered_map<char, string>& codes) {
if (!root) return;
if (root->data != '$') {
codes[root->data] = code;
}
generateCodes(root->left, code + "0", codes);
generateCodes(root->right, code + "1", codes);
}
// 根据哈夫曼编码解码字符串
string decodeHuffman(Node* root, string encoded) {
string decoded = "";
Node* current = root;
for (char bit : encoded) {
if (bit == '0') {
current = current->left;
} else {
current = current->right;
}
if (!current->left && !current->right) {
decoded += current->data;
current = root;
}
}
return decoded;
}
int main() {
int n;
cin >> n;
priority_queue<Node*, vector<Node*>, Compare> pq;
for (int i = 0; i < n; ++i) {
char data;
int freq;
cin >> data >> freq;
Node* node = new Node(data, freq);
pq.push(node);
}
Node* root = buildHuffmanTree(pq);
unordered_map<char, string> codes;
generateCodes(root, "", codes);
string input;
cin.ignore(); // 忽略换行符
while (getline(cin, input)) {
if (isdigit(input[0])) { // 输入的是哈夫曼编码,解码
cout << decodeHuffman(root, input) << endl;
} else { // 输入的是字母串,编码
string encoded = "";
for (char c : input) {
encoded += codes[c];
}
cout << encoded << endl;
}
}
delete root; // 释放树的内存
return 0;
结果实现: