Cod sursa(job #2418700)

Utilizator r00t_Roman Remus r00t_ Data 5 mai 2019 20:17:10
Problema Coduri Huffman Scor 30
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.22 kb
#include <iostream>
#include <vector>
#include <queue>
#include <string>
#include <math.h>
#include <fstream>
#include <algorithm>

using namespace std;

ifstream fin("huffman.in");
ofstream fout("huffman.out");

struct HuffmanCodes
{
	struct Node
	{
		int data;
		size_t freq;
		Node* left;
		Node* right;

		Node() :data(0), freq(0), left(nullptr), right(nullptr) {};
		Node(int data, size_t freq) :data(data), freq(freq), left(nullptr), right(nullptr) {};
	};

	struct cmp
	{
		bool operator()(Node* l, Node* r)
		{
			return l->freq > r->freq;
		}
	};

	Node* top;
	vector<pair<int, string>> rez;

	void printCodes(Node* root, string str, vector<pair<int,string>>& rez)
	{
		if (root == nullptr) return;
		if (root->data != -1)
		{
			//do magic here;
			rez.push_back(make_pair(root->data, str));
			cout << root->data << ':' << str <<'\n';
		}
		printCodes(root->left, str + "0", rez);
		printCodes(root->right, str + "1", rez);
	}

	void buildCode(vector<int>& data, vector<size_t>& freq)
	{
		priority_queue<Node*, vector<Node*>, cmp> minHeap;
		Node* left;
		Node* right;

		for (int i = 0; i < data.size(); i++)
		{
			minHeap.push(new Node(data[i], freq[i]));
		}

		while (minHeap.size() != 1) {
			left = minHeap.top();
			minHeap.pop();

			right = minHeap.top();
			minHeap.pop();

			top = new Node(-1, left->freq + right->freq);
			top->left = left;
			top->right = right;

			minHeap.push(top);
		}
		printCodes(minHeap.top(), "", rez);
	}


};

int strToInt(string a)
{
	int rez = 0;
	for (int i = 0; i < a.size(); i++)
	{
		if (a[i] == '1') rez += pow(2, a.size()-1-i);
	}
	
	return rez;
}

int main()
{
	ios_base::sync_with_stdio(0);
	HuffmanCodes set1;
	vector<size_t> freq;
	vector<int> data;
	int n;
	fin >> n;
	for (int i = 0; i < n; i++)
	{
		size_t aux;
		fin >> aux;
		freq.push_back(aux);
		data.push_back(i);
	}
	set1.buildCode(data, freq);
	sort(set1.rez.begin(), set1.rez.end());
	int sz = 0;
	for (int i = 0; i < freq.size(); i++) sz += set1.rez[i].second.size()*freq[i];
	fout << sz <<'\n';
	for (int i = 0; i < set1.rez.size(); i++)
	{
		fout << set1.rez[i].second.size() << ' ' << strToInt(set1.rez[i].second) << '\n';
	}
}