/** (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