Pagini recente » Cod sursa (job #2396956) | Cod sursa (job #606196) | Cod sursa (job #2294732) | Cod sursa (job #1310818) | Cod sursa (job #1216765)
#include <fstream>
#include <queue>
using namespace std;
ifstream in("huffman.in");
ofstream out("huffman.out");
class Node {
public:
Node(unsigned _symId, unsigned _occrs) :
symId(_symId),
occrs(_occrs),
parent(nullptr),
isOne(false)
{
childs[0] = nullptr;
childs[1] = nullptr;
}
Node(Node* child0, Node* child1) :
symId(0),
isOne(false),
occrs(child0->occrs + child1->occrs)
{
childs[0] = child0;
child0->parent = this;
childs[1] = child1;
child1->parent = this;
child1->isOne = true;
symId = 0;
}
friend ostream& operator<<(ostream& os, const Node &node) {
os << node.symId << ':' << node.occrs << ':' << node.isOne;
return os;
}
bool getCode() const {
return isOne;
}
Node* getParent() const {
return parent;
}
unsigned getOccrs() const {
return occrs;
}
private:
bool isOne;
unsigned occrs;
Node* parent;
Node* childs[2];
unsigned symId;
};
struct Code {
unsigned long long code;
unsigned lvl;
};
Code getCode(const Node* nd, unsigned lvl) {
if(nd->getParent()) {
Code c = getCode(nd->getParent(),lvl+1);
c.code += nd->getCode()*(1ull<<lvl);
return c;
}
else {
return {0,lvl};
}
}
bool comp(const Node* a, const Node* b) {
return a->getOccrs() > b->getOccrs();
}
int main() {
priority_queue<Node*,vector<Node*>,decltype(&comp)> huffQueue(&comp);
size_t nrSyms;
in >> nrSyms;
vector<Node*> syms(nrSyms+1, nullptr);
for(size_t i = 1; i <= nrSyms; ++i) {
unsigned nrOccrs;
in >> nrOccrs;
syms[i] = new Node(i,nrOccrs);
huffQueue.push(syms[i]);
}
Node *child0, *child1;
while(huffQueue.size() > 2) {
child0 = huffQueue.top(); huffQueue.pop();
child1 = huffQueue.top(); huffQueue.pop();
huffQueue.push(new Node(child0,child1));
}
child0 = huffQueue.top(); huffQueue.pop();
child1 = huffQueue.top(); huffQueue.pop();
Node* parent = new Node(child0,child1);
vector<Code> codes(nrSyms+1);
unsigned long long len = 0;
for(size_t i = 1; i <= nrSyms; ++i) {
codes[i] = getCode(syms[i],0);
len += codes[i].lvl*syms[i]->getOccrs();
}
out << len << '\n';
for(size_t i = 1; i <= nrSyms; ++i) {
out << codes[i].lvl << ' ' << codes[i].code << '\n';
}
}