开始计概A下半学期。
This commit is contained in:
1 parent
0cfdc8499c
commit
38e97654e1
31 files changed
+2144
-110
No files matched your search
@@ -0,0 +1,112 @@
|
||||
#include <functional>
|
||||
#include <iostream>
|
||||
#include <optional>
|
||||
#include <queue>
|
||||
#include <unordered_map>
|
||||
#include <utility>
|
||||
|
||||
class HuffmanTree {
|
||||
public:
|
||||
struct Node {
|
||||
long long weight;
|
||||
std::optional<std::string> content;
|
||||
Node *left = nullptr, *right = nullptr;
|
||||
|
||||
bool operator<(const Node& other) const {
|
||||
return weight < other.weight;
|
||||
}
|
||||
};
|
||||
|
||||
enum class DfsEntries { Pre, In, Post };
|
||||
|
||||
Node* root = nullptr;
|
||||
|
||||
explicit HuffmanTree(const std::unordered_map<std::string, long long>& freq_map) {
|
||||
std::priority_queue<Node*, std::vector<Node*>,
|
||||
std::function<bool(Node*, Node*)>>
|
||||
nodes_heap([](Node* a, Node* b) { return a->weight > b->weight; });
|
||||
for (const auto& [key, freq] : freq_map) {
|
||||
nodes_heap.push(new Node{.weight = freq, .content = key});
|
||||
}
|
||||
while (nodes_heap.size() > 1) {
|
||||
Node* node1 = nodes_heap.top();
|
||||
nodes_heap.pop();
|
||||
Node* node2 = nodes_heap.top();
|
||||
nodes_heap.pop();
|
||||
Node* new_node = new Node{.weight = node1->weight + node2->weight, .left = node1, .right = node2};
|
||||
nodes_heap.push(new_node);
|
||||
}
|
||||
root = nodes_heap.top();
|
||||
}
|
||||
|
||||
std::unordered_map<std::string, std::vector<bool>> get_encodings() {
|
||||
std::unordered_map<std::string, std::vector<bool>> encodings;
|
||||
if (root->left == nullptr && root->right == nullptr) {
|
||||
encodings[root->content.value()] = {false};
|
||||
} else {
|
||||
dfs_with_path([&encodings](Node* node, std::vector<bool> path) {
|
||||
if (!node->content.has_value()) { return; }
|
||||
encodings[node->content.value()] = std::move(path);
|
||||
});
|
||||
}
|
||||
return encodings;
|
||||
}
|
||||
|
||||
protected:
|
||||
void dfs_with_path(const std::function<void(Node*, std::vector<bool>)>& func,
|
||||
DfsEntries func_entry = DfsEntries::Pre) {
|
||||
std::vector<bool> path;
|
||||
dfs_with_path(func, func_entry, path);
|
||||
}
|
||||
|
||||
void dfs_with_path(const std::function<void(Node*, std::vector<bool>)>& func,
|
||||
DfsEntries func_entry,
|
||||
std::vector<bool>& path,
|
||||
Node* node = nullptr) {
|
||||
if (node == nullptr) { node = root; }
|
||||
if (func_entry == DfsEntries::Pre) { func(node, path); }
|
||||
if (node->left != nullptr) {
|
||||
path.push_back(false);
|
||||
dfs_with_path(func, func_entry, path, node->left);
|
||||
path.pop_back();
|
||||
}
|
||||
if (func_entry == DfsEntries::In) { func(node, path); }
|
||||
if (node->right != nullptr) {
|
||||
path.push_back(true);
|
||||
dfs_with_path(func, func_entry, path, node->right);
|
||||
path.pop_back();
|
||||
}
|
||||
if (func_entry == DfsEntries::Post) { func(node, path); }
|
||||
}
|
||||
};
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const std::vector<bool>& bintree_path) {
|
||||
for (const auto bin : bintree_path) {
|
||||
os << (bin ? 1 : 0);
|
||||
}
|
||||
return os;
|
||||
}
|
||||
|
||||
int main() {
|
||||
std::ios::sync_with_stdio(false);
|
||||
std::cin.tie(nullptr);
|
||||
|
||||
int n;
|
||||
std::cin >> n;
|
||||
|
||||
std::vector<std::string> keys(n);
|
||||
std::unordered_map<std::string, long long> freq_map;
|
||||
for (int i = 0; i < n; i++) {
|
||||
int freq;
|
||||
std::cin >> keys[i] >> freq;
|
||||
freq_map[keys[i]] = freq;
|
||||
}
|
||||
|
||||
HuffmanTree huffman_tree(freq_map);
|
||||
auto encodings = huffman_tree.get_encodings();
|
||||
for (const auto& key : keys) {
|
||||
std::cout << key << ' ' << encodings[key] << std::endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in new issue
Block a user