Creative Commons License Foxbond's Repo

/** (c) 2016 Michał (Foxbond) Chraniuk */
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <vector>
#include <algorithm>

using namespace std;

//Struktura dla Modelu zrodla informacji ORAZ tabeli kodowej
typedef struct MZIElem {
	int znak;
	int count;
	char* kod;
	MZIElem(int z, int c) : znak(z), count(c) {}
}MZIElem;

//umozliwia proste sortowanie
bool MZISort(MZIElem* a, MZIElem* b) {
	return a->count > b->count;
}

//Struktura dla tabeli drzewa kodowego
typedef struct TDKElem {
	int znak;
	int left = NULL;
	int right = NULL;
	TDKElem(int z, int l, int r) : znak(z), left(l), right(r) {}
}TDKElem;

//funkcja przepisujaca ciag znakow od tylu
char* strrev(char* s)
{
	char  c;
	char* s0 = s - 1;
	char* s1 = s;

	while (*s1) ++s1;

	while (s1-- > ++s0)
	{
		c = *s0;
		*s0 = *s1;
		*s1 = c;
	}

	return s;
}

int main() {

	int tab[256];
	int c;
	//int count = 0;
	vector<MZIElem*> MZI;
	MZIElem* temp;
	TDKElem* temp2;

	for (int i = 0;i < 256;i++) {
		tab[i] = 0;
	}

	FILE *we = fopen("we.txt", "r");
	FILE *pmzi = fopen("ModelZrodlaInf.txt", "w");
	FILE *pdk = fopen("DrzewoKodowania.txt", "w");
	FILE *ptk = fopen("TabelaKodowa.txt", "w");

	if (we == NULL) {
		printf("Nie udalo sie otworzyc pliku wejsciowego!");
		return 0;
	}

	if (pmzi == NULL || pdk == NULL || ptk == NULL) {
		printf("Nie udalo sie otworzyc/utworzyc pliku wyjsciowego!");
		return 0;
	}

	//zliczamy znaki wystepujace w pliku zrodlowym
	while ((c = fgetc(we)) != EOF) {
		//if (tab[c] == 0) count++;

		tab[c]++;
	}

	//tworzymy MZI na podstawie zliczonych znakow
	for (int i = 0;i < 256;i++) {
		if (tab[i] != 0) {
			temp = new MZIElem(i, tab[i]);
			MZI.push_back(temp);
		}
	}

	//sortujemy MZI
	sort(MZI.begin(), MZI.end(), MZISort);

	vector<MZIElem*> emzi;

	//Zapisujemy MZI do plku oraz tworzymy tablice pomocnicza do stworzenia tablicy drzewa kodowania
	for (int i = 0;i < MZI.size();i++) {
		fprintf(pmzi, "%3d : %c : %d\n", MZI[i]->znak, MZI[i]->znak, MZI[i]->count);
		temp = new MZIElem(MZI[i]->znak, MZI[i]->count);
		emzi.push_back(temp);
	}

	//tworzymy Tablice drzewa kodowania
	int symbol = 0;
	vector<TDKElem*> tdk;
	while (emzi.size() > 1) {
		MZIElem *one = emzi.back();
		emzi.pop_back();
		MZIElem *two = emzi.back();
		emzi.pop_back();

		temp = new MZIElem(--symbol, one->count + two->count);
		emzi.push_back(temp);

		temp2 = new TDKElem(symbol, one->znak, two->znak);
		tdk.push_back(temp2);
		sort(emzi.begin(), emzi.end(), MZISort);
	}

	//zapisujemy TDK do pliku
	for (int i = 0;i < tdk.size();i++) {
		fprintf(pdk, "%d : %d : %d\n", tdk[i]->znak, tdk[i]->left, tdk[i]->right);
	}

	//tworzymy słowa kodowe
	for (int i = 0;i < MZI.size();i++) {
		MZI[i]->kod = new char[symbol*(-1) + 1];
		int tZnak = MZI[i]->znak;
		int currPos = 0;
		while (tZnak != symbol) {
			for (int q = 0;q < tdk.size();q++) {
				if (tZnak == tdk[q]->left) {
					MZI[i]->kod[currPos++] = '0';
					tZnak = tdk[q]->znak;
					break;
				}
				if (tZnak == tdk[q]->right) {
					MZI[i]->kod[currPos++] = '1';
					tZnak = tdk[q]->znak;
					break;
				}
			}
		}
		MZI[i]->kod[currPos] = '\0';
		strrev(MZI[i]->kod);
	}

	//zapisujemy Tablice kodowania do pliku
	for (int i = 0;i < MZI.size();i++) {
		fprintf(ptk, "%c | %3d | %s\n", MZI[i]->znak, MZI[i]->znak, MZI[i]->kod);
	}

	fclose(we);
	fclose(pmzi);
	fclose(pdk);
	fclose(ptk);
	
	return 0;
}

> Back