Pagini recente » Cod sursa (job #1575715) | Cod sursa (job #3269884) | Cod sursa (job #1429799) | Cod sursa (job #2466048) | Cod sursa (job #3133111)
#include <iostream>
#include <fstream>
#include <queue>
#include <vector>
#include <algorithm>
#include <string>
using namespace std;
struct Node {
int symbol;
long long frequency;
Node* left;
Node* right;
Node(int symbol, long long frequency) : symbol(symbol), frequency(frequency), left(nullptr), right(nullptr) {}
};
struct CompareNodes {
bool operator()(const Node* a, const Node* b) const {
return a->frequency > b->frequency;
}
};
void generateHuffmanCodes(Node* root, const string& codePrefix, vector<pair<int, string>>& huffmanCodes) {
if (root->left == nullptr && root->right == nullptr) {
huffmanCodes.emplace_back(root->symbol, codePrefix);
return;
}
generateHuffmanCodes(root->left, codePrefix + "0", huffmanCodes);
generateHuffmanCodes(root->right, codePrefix + "1", huffmanCodes);
}
long long huffmanEncoding(const vector<long long>& frequencies, vector<pair<int, string>>& huffmanCodes) {
priority_queue<Node*, vector<Node*>, CompareNodes> pq;
for (int i = 0; i < frequencies.size(); i++) {
if (frequencies[i] > 0) {
pq.push(new Node(i, frequencies[i]));
}
}
while (pq.size() > 1) {
Node* leftChild = pq.top();
pq.pop();
Node* rightChild = pq.top();
pq.pop();
Node* internalNode = new Node(-1, leftChild->frequency + rightChild->frequency);
internalNode->left = leftChild;
internalNode->right = rightChild;
pq.push(internalNode);
}
Node* root = pq.top();
pq.pop();
generateHuffmanCodes(root, "", huffmanCodes);
long long encodedLength = 0;
for (const auto& code : huffmanCodes) {
encodedLength += frequencies[code.first] * code.second.length();
}
return encodedLength;
}
int main() {
ifstream fin("huffman.in");
ofstream fout("huffman.out");
int n;
fin >> n;
vector<long long> frequencies(n);
for (int i = 0; i < n; i++) {
fin >> frequencies[i];
}
vector<pair<int, string>> huffmanCodes;
long long encodedLength = huffmanEncoding(frequencies, huffmanCodes);
fout << encodedLength << "\n";
for (const auto& code : huffmanCodes) {
fout << code.second.length() << " " << code.second << "\n";
}
fin.close();
fout.close();
return 0;
}