Descripción de los algoritmos desarrollados - Sormocs/Proyecto_III_Datos_II GitHub Wiki
Ingresado un string, se genera la un vector con cada char del string para posteriormente convertir esos char en bytes, de modo que se nos genere una cadena de bytes almacenada en un vector. Para el proceso anterior, separamos la cadena de 1's y 0's en espacios de 8, para generar un byte, convertirlo a char y por último generar el string a partir de los chars ingreados.
vector<char> BytesConverter::GetChars(std::string text) {
vector<char> v(text.begin(), text.end());
return v;
}
vector<bitset<8>> BytesConverter::GetBytes(std::vector<char> v) {
vector<bitset<8>> b;
for (int i = 0; i < v.size(); ++i) {
std::bitset<8> bitset(v.at(i));
b.push_back(bitset);
}
return b;
}
string BytesConverter::BytestoString(std::vector<bitset<8>> b) {
string temp = "";
for (int i = 0; i < b.size(); ++i) {
temp += b.at(i).to_string();
}
this->text = temp;
return temp;
}
vector<bitset<8>> BytesConverter::GetBytesChar(std::string text) {
vector<bitset<8>> b;
int size = text.length()/8;
for (int i = 0; i < size; i++) {
bitset<8> byte(text.substr(0,8));
b.push_back(byte);
if (text.length() != 8){
text = text.substr(8,text.length());
}
}
return b;
}
vector<char> BytesConverter::BytesToChar(std::vector<bitset<8>> b) {
vector<char> c;
for (int i = 0; i < b.size(); ++i) {
unsigned long k = b.at(i).to_ulong();
char caracter = static_cast<char>( k );
c.push_back(caracter);
}
return c;
}
string BytesConverter::GenerateString(std::vector<char> c) {
string temp;
for (int i = 0; i < c.size(); i++) {
temp.push_back(c.at(i));
}
return temp;
}
Comienza recibiendo un string cualquiera, el cual procesa en sus metodos para obtener cada caractér con su frecuencia respectiva, para de allí comenzar a formar el árbol de Huffman y obteneer el mensaje codificado y comprimido. Lo hace mediante la ayuda de la listaa enlazada StrChar, la cual almacena el valor del a frecuencia de cada caractér junto con este mismo. Se recorre el string y se revisa si el caractér ya se encuentra en la lista, si se encuentra, se aumenta en uno la frecuencia, pero si no se encuentra se crea un nuevo nodo en la lista. De aquí, pasa a formar el árbol, el cuál es un extenso proceso en el cuál los nodos del mismo se crean con 2 caractéres cada uno, y de ahí se van acomodando según la frecuencia, agrupando los nodos en otros nodos que van colocando las frecuencias menores más abajo, para finalmente formar el diccionario con ayuda de dos funciones que son printCodes y printArr, las cuales aparte de mostrar en consola el diccionario obtenido, introducen cada caractér con su código en el árbol en el diccionario.
struct MinHeapNode* Huffman::newNode(char data, unsigned freq)
{
struct MinHeapNode* temp = (struct MinHeapNode*)malloc(sizeof(struct MinHeapNode));
temp->left = temp->right = NULL;
temp->data = data;
temp->freq = freq;
return temp;
}
El anterior es un ejemplo de un metodo que crea el nodo nuevo con la información que recibe. Los nodos consisten en los siguientes structs:
struct MinHeapNode {
char data;
unsigned freq;
struct MinHeapNode *left, *right;
};
struct MinHeap {
unsigned size;
unsigned capacity;
struct MinHeapNode** array;
};
Luego, para el decode, se recibe un json que contiene toda la información del árbol de huffman, como el mensaje codificado y el código de cada caractér, para así recrear el mensaje sin problemas y se continue con el flujo normal, vuelve a generar el diccionario a partir del json obtenido.