Homework New
This commit is contained in:
140
Exercise/Homework5/Huffman.cpp
Normal file
140
Exercise/Homework5/Huffman.cpp
Normal file
@@ -0,0 +1,140 @@
|
||||
#include <bits/stdc++.h>
|
||||
using namespace std;
|
||||
|
||||
struct Node {
|
||||
char ch; // <20><><EFBFBD>ڷ<EFBFBD>Ҷ<EFBFBD>ڵ㣬ch = 0
|
||||
int freq;
|
||||
bool isLeaf;
|
||||
int firstPos; // <20><><EFBFBD>ı<EFBFBD><C4B1><EFBFBD><EFBFBD>״γ<D7B4><CEB3>ֵ<EFBFBD>λ<EFBFBD>ã<EFBFBD><C3A3><EFBFBD><EFBFBD><EFBFBD> tie-break<61><6B>
|
||||
Node *left, *right;
|
||||
int createOrder; // <20><><EFBFBD><EFBFBD>˳<EFBFBD><CBB3><EFBFBD><EFBFBD><EFBFBD>ţ<EFBFBD><C5A3><EFBFBD><EFBFBD>ڷǵ<DAB7><C7B5>ڵ<EFBFBD><DAB5>Ƚ<EFBFBD>
|
||||
|
||||
Node(char c, int f, int pos, int order)
|
||||
: ch(c), freq(f), isLeaf(true), firstPos(pos),
|
||||
left(NULL), right(NULL), createOrder(order) {}
|
||||
|
||||
Node(Node* l, Node* r, int f, int order)
|
||||
: ch(0), freq(f), isLeaf(false), firstPos(INT_MAX),
|
||||
left(l), right(r), createOrder(order) {}
|
||||
};
|
||||
|
||||
/*
|
||||
<20><><EFBFBD>ȶ<EFBFBD><C8B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
1. ȨֵС<D6B5><D0A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
2. Ȩֵ<C8A8><D6B5><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>
|
||||
a. <20><><EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڷǵ<DAB7><C7B5>ڵ<EFBFBD>
|
||||
b. <20><><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA><EFBFBD>ڵ<EFBFBD> <20><> <20><> firstPos С<><D0A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
c. <20><><EFBFBD><EFBFBD>Ϊ<EFBFBD>ǵ<EFBFBD><C7B5>ڵ<EFBFBD> <20><> <20><> createOrder С<><D0A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
*/
|
||||
struct Cmp {
|
||||
bool operator()(Node* a, Node* b) {
|
||||
if (a->freq != b->freq) return a->freq > b->freq;
|
||||
|
||||
// freq <20><>ͬ
|
||||
if (a->isLeaf != b->isLeaf) return a->isLeaf < b->isLeaf;
|
||||
|
||||
if (a->isLeaf) return a->firstPos > b->firstPos;
|
||||
return a->createOrder > b->createOrder;
|
||||
}
|
||||
};
|
||||
|
||||
unordered_map<char, string> codeMap;
|
||||
|
||||
// <20><><EFBFBD>ɹ<EFBFBD><C9B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
void dfs(Node* root, string path) {
|
||||
if (!root) return;
|
||||
if (root->isLeaf) {
|
||||
codeMap[root->ch] = path;
|
||||
return;
|
||||
}
|
||||
dfs(root->left, path + "0");
|
||||
dfs(root->right, path + "1");
|
||||
}
|
||||
|
||||
// <20>ù<EFBFBD><C3B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƴ<EFBFBD>
|
||||
string decode(Node* root, const string& s) {
|
||||
string result;
|
||||
Node* cur = root;
|
||||
for (char c : s) {
|
||||
if (c == '0') cur = cur->left;
|
||||
else if (c == '1') cur = cur->right;
|
||||
else return "INVALID";
|
||||
|
||||
if (!cur) return "INVALID";
|
||||
if (cur->isLeaf) {
|
||||
result.push_back(cur->ch);
|
||||
cur = root;
|
||||
}
|
||||
}
|
||||
if (cur != root) return "INVALID"; // δ<><CEB4>Ҷ<EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD><EFBFBD>
|
||||
return result;
|
||||
}
|
||||
|
||||
int main() {
|
||||
ios::sync_with_stdio(false);
|
||||
cin.tie(NULL);
|
||||
|
||||
string text, code1, code2;
|
||||
cin >> text >> code1 >> code2;
|
||||
|
||||
// ͳ<>Ƴ<EFBFBD><C6B3>ִ<EFBFBD><D6B4><EFBFBD> & <20>״γ<D7B4><CEB3><EFBFBD>λ<EFBFBD><CEBB>
|
||||
unordered_map<char, int> freq, firstPos;
|
||||
for (int i = 0; i < text.size(); i++) {
|
||||
char c = text[i];
|
||||
freq[c]++;
|
||||
if (!firstPos.count(c)) firstPos[c] = i;
|
||||
}
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȶ<EFBFBD><C8B6><EFBFBD>
|
||||
priority_queue<Node*, vector<Node*>, Cmp> pq;
|
||||
int createId = 0;
|
||||
|
||||
for (auto& p : freq) {
|
||||
char c = p.first;
|
||||
int f = p.second;
|
||||
pq.push(new Node(c, f, firstPos[c], createId++));
|
||||
}
|
||||
|
||||
// <20><><EFBFBD><EFBFBD>Ψһ<CEA8><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
while (pq.size() > 1) {
|
||||
Node* a = pq.top(); pq.pop();
|
||||
Node* b = pq.top(); pq.pop();
|
||||
Node* parent = new Node(a, b, a->freq + b->freq, createId++);
|
||||
pq.push(parent);
|
||||
}
|
||||
|
||||
Node* root = pq.top();
|
||||
|
||||
// <20><><EFBFBD>ɱ<EFBFBD><C9B1><EFBFBD>
|
||||
dfs(root, "");
|
||||
|
||||
// <20><><EFBFBD><EFBFBD>ѹ<EFBFBD><D1B9>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD>С
|
||||
int originalBytes = text.size();
|
||||
long long bits = 0;
|
||||
for (char c : text) bits += codeMap[c].size();
|
||||
long long compressedBytes = (bits + 7) / 8;
|
||||
|
||||
cout << originalBytes << " " << compressedBytes << "\n";
|
||||
|
||||
// <20><><EFBFBD><EFBFBD>ĿҪ<C4BF><D2AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>루<EFBFBD><EBA3A8>Ƶ<EFBFBD><C6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͬƵ<CDAC>ʰ<EFBFBD><CAB0><EFBFBD><EFBFBD><EFBFBD>˳<EFBFBD><CBB3><EFBFBD><EFBFBD>
|
||||
vector<tuple<int,int,char>> order;
|
||||
for (auto& p : freq) {
|
||||
order.emplace_back(p.second, firstPos[p.first], p.first);
|
||||
}
|
||||
sort(order.begin(), order.end());
|
||||
|
||||
for (auto& t : order) {
|
||||
char c = get<2>(t);
|
||||
cout << c << ":" << codeMap[c] << "\n";
|
||||
}
|
||||
|
||||
// <20><><EFBFBD><EFBFBD>
|
||||
string out1 = decode(root, code1);
|
||||
string out2 = decode(root, code2);
|
||||
|
||||
cout << out1 << "\n";
|
||||
cout << out2 << "\n";
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user