Cod sursa(job #1216765)

Utilizator alexandru70Ungurianu Alexandru alexandru70 Data 5 august 2014 18:00:24
Problema Coduri Huffman Scor 65
Compilator cpp Status done
Runda Arhiva educationala Marime 2.12 kb
#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';
	}

}