Red de conocimiento informático - Conocimiento del nombre de dominio - Buscando ansiosamente el programa fuente de la implementación de codificación c de Huffman

Buscando ansiosamente el programa fuente de la implementación de codificación c de Huffman

int get_code_len(int index)

{

check();

if (index < 0 || index >= (int)code_lens.size() )

lanzar nueva excepción huffman_("Argumento ilegal");

devolver code_lens[index];

}

vector get_all_code_lens(void)

{

check();

devuelve code_lens;

}

sin firmar long get_code(int index)

{

check();

if (index < 0 || index >= (int)codes.size() )

throw new huffman_exception("Argumento ilegal");

códigos de retorno[index];

}

vector get_all_codes( void)

{

check();

código de retorno;

}

cadena get_code_str(int index)

{

check();

if (index & lt; 0 || index >= (int)codes.size( ))

throw new huffman_exception("Argumento ilegal");

return long_to_string(codes[index], code_lens[index]);

}

vector<string> get_all_code_strs(void)

{

check();

vector v;

for( int i = 0; i < (int)codes.size(); i++)

v.push_back(long_to_string(codes[i], code_lens[i]));

return v;

}

int find(código largo sin firmar)

{

check();

for(int i = 0; i < (int)codes.size(); i++)

if (codes[i] == código)

return i;

return -1;

}

int find(const string& code)

{

return find(string_to_long (code.c_str()));

}

verificación nula en línea()

{

if (codes.size( ) <= 0)

p>

throw new huffman_exception("generate_codes()") aún no ha sido llamado";

}

unsigned long string_to_long(const char* code)

{

unsigned long ret = 0;

int len ​​​​= (int)strlen(código);

for(int i = len - 1 ; i >= 0; i--)

si (código[i] == '1')

ret |= (1ul << (len - i - 1) );

return ret;

}

string long_to_string(código largo sin firmar, int code_len)

{

char* buf = new char[code_len + 1];

if (buf == NULL)

throw new huffman_exception("no hay suficiente memoria.");

memset(buf, 0, code_len + 1);

bit largo sin signo = 1 << (code_len - 1);

for(int i = 0 ; i < code_len; i++)

{

if (código y bit)

buf[i] = '1'; > else

buf[i] = '0';

bit >>= 1;

}

cadena ret(buf ); eliminar buf;

devolver ret;

}

void generate_canonical_codes()

{

si (code_lens .size() <= 0)

Genera una nueva excepción huffman_ ("La longitud del código de todos los elementos debe conocerse antes de generar el código canónico de Huffman");

int max_code_len = 0 ;

int min_code_len = 1000;

const int tmp = sizeof( unsigned long) * 8 + 1

int len_count[tmp]; /p >

unsigned long min_code[tmp];

memset(len_count, 0, tmp * sizeof(int));

memset(min_code, 0, tmp * sizeof) (unsigned long));

int num = (int)code_lens.size();

// Información estadística sobre la longitud del código

for (int i = 0; i < num; i++)

{

int codelen = code_lens[i];

// huffman_base usa un código largo sin firmar, por lo que <

/p>

// La longitud del código debe limitarse a sizeof(unsigned long)*8

// Aquí, se ignorará la longitud excesiva del código.

If ((unsigned long)codelen > sizeof(unsigned long)*8)

Continuar

If (codelen > max_code_len)

max_ code_len = codelen;

if (codelen < min_code_len)

min_code_len = codelen;

len_count[codelen]++;

}

if (unsigned long)codelen > sizeof(unsigned long)*8)

Continuar.

// Calcula el código más pequeño entre todos los elementos con una longitud de código específica. Aquí, se utiliza el código más pequeño entre todos los elementos con una longitud de código específica.

// Codificación canónica de Huffman. reglas, consulte literatura relacionada

para (int i = max_code_len - 1; i > = 0; i--)

min_code[i] = (min_code[i + 1] + len_count[ i + 1]) >> 1;

// Entre todos los elementos con una longitud de código específica, el código más pequeño del elemento con la misma longitud de código,

// Solo necesitas agregar 1 al código uno por uno

codes.clear();

for (int i = 0; i < num; i ++)

if (code_lens [i] > 0 && (unsigned long)code_lens[i] <= sizeof(unsigned long)*8)

codes.push_back(min_code[code _lens[i] ]++);

else

codes.push_back(0);

}

bool verificar()

{

check();

int max = 0;

const int code_len_limit = 100 // La longitud máxima del código que se puede verificar; aquí está 100

int len_count[code_len_limit + 1];

memset(len_count, 0, sizeof(int)*(code_len_limit+ 1));

para (int i = 0; i < (int )code_lens.size(); i++)

{

If (code_lens[i] > code_len_limit)

return true; // Si hay un código demasiado largo, no se realizará ninguna prueba

len_count[code_lens[i]]++;

If (code_lens[i] > ; max) max = code_lens[i];

}

// Comenzando desde la raíz, calcula el número de nodos de rama en cada nivel. El último nivel no es 0, significa un error del árbol de Huffman

int nonleaf = 1;

for(int i = 1; i <= max; i++)

nonleaf = nonleaf * 2 - len_count[i];

return (nonleaf == 0);

}

// Función principal

void generate_codes(int num, const unsigned long* pesos)

{

if (num <= 1 || pesos == NULL)

lanza una nueva huffman_exception ("parámetro ilegal");

int heap_num, i, nonzero_count;

// Asigna una estructura de montón utilizada para generar un árbol de Huffman, su tamaño es el doble de elementos

unsigned long* heap = new unsign

ed long[2*num];

if (heap == NULL) throw new huffman_exception("Sin memoria");

// Copia todos los pesos de los elementos (nodos hoja) a la segunda mitad del montón y establezca la primera mitad en 0

memcpy(heap + num,weights, sizeof(unsigned long)*num);

memset((char * )heap, 0, num * sizeof (*heap));

// Trata la primera mitad del montón como un puntero, apuntando a la segunda mitad de los nodos hoja en secuencia

// También calcula el número de nodos hoja con peso distinto de cero

for (nonzero_count = i = 0; i < num; i++)

if (heap[num + i])

montón[nonzero_count++] = num + i; registrar temperatura larga sin firmar;

temp = montón[niño - 1];

montón[niño - 1] = montón [curr - 1];

montón[curr - 1] = temp;

curr = niño;

niño = 2 * curr ;

}

más

romper;

}

}

}

/* Crear árbol Huffman

Aquí, el proceso de creación del árbol Huffman utiliza el principio básico de clasificación de montón. El proceso de creación de un árbol de Huffman aquí utiliza los principios básicos del algoritmo de clasificación del montón, donde el nodo raíz es el elemento más pequeño y el último elemento del árbol es el elemento más grande. Después de seleccionar el nodo raíz, el último elemento se mueve al nodo raíz

y luego se reconstruye el montón moviendo el último elemento desde la raíz a las hojas del árbol. Con este enfoque, siempre puedes encontrar los dos subárboles más pequeños, fusionarlos y colocarlos en el montón como elementos nuevos. Una vez que se fusionan todos los subárboles, el árbol de Huffman estará completo. (Para obtener una introducción al algoritmo de clasificación de montones, consulte los libros sobre estructuras de datos o algoritmos).

El resultado de este código es un árbol de Huffman que consta de todos los montones, donde no se utiliza el montón [0]. La raíz del árbol

montón[1] guarda la suma de todos los valores, montón[2]..heap[num-1] corresponde a todos los nodos de rama excepto el nodo raíz

, guardar El valor de índice del nodo principal, montón [núm].

.heap[num*2-1] corresponde a todos los

nodos hoja (es decir, todos los elementos que se van a codificar) y almacena el valor de índice del nodo principal*/

/* When Loop cuando todavía hay nodos en el árbol binario para la clasificación del montón*/

while (heap_num > 1)

{

int pos[ 2];

p>

/* Realiza un bucle 2 veces, encuentra los 2 subárboles más pequeños y colócalos en pos*/

for (i = 0; i < 2; i++)

{

Register int curr, child;

/* El nodo raíz es el nodo más pequeño*/

pos[i] = heap[0] ;

/* Mueve el último nodo al nodo raíz y reduce el número de nodos en 1 */

heap[0] = heap[--heap_num ];

/* Aquí se explica cómo reconstruir el montón*/

curr = 1;

child = 2

while; (niño <= núm_montón)

{

if (niño < núm_montón &&

montón[montón[niño]] < montón[montón[niño - 1 ]])

niño++;

if (montón[montón[curr - 1]] > montón[montón[niño - 1]])

{

registro int temp;

temp = montón[niño - 1];

montón[niño - 1] = montón[curr - 1];

montón[ curr - 1] = temp;

curr = niño;

niño = 2 * curr;

}

else

break;

}

}

}

/* Fusionar subárboles, el El resultado combinado será un nuevo El nodo se coloca en el montón (pero no en un árbol binario ordenado en montón; en la práctica, el nodo recién agregado y la segunda mitad del montón forman un árbol de Huffman) */

montón[heap_num + 1] = montón[pos[0]]+ montón[ pos[1]];

/* Las ramas izquierda y derecha del subárbol apuntan al nodo raíz del subárbol */

montón[pos[0]] = montón[pos[1]] = montón_num + 1;

/* En la clasificación del montón, se utiliza el nodo raíz del subárbol como nodo hoja del árbol binario* /

montón[ heap_num] = heap_num + 1;

{

/* En el montón, deje que el nuevo El nodo hoja agregado se eleva a la posición correcta, sin destruir el orden del montón*/

registrar int parent, curr;

heap_num++;

curr = heap_num ;

padre = curr >> 1;

mientras (padre && montón[montón[padre - 1]] > montón[montón[curr - 1]])

{

registro int temp;

temp =

montón[padre - 1];

montón[padre - 1] = montón[curr - 1];

montón[curr - 1] = temporal;

curr = parent;

parent = curr >> 1;

}

}

// cada uno comenzando desde el Código raíz longitud del código

code_lens.clear();

heap[0] = (unsigned long)(-1l); // La hoja cuyo nodo padre es 0 se puede calcular a partir de it La longitud del código de salida es 0

heap[1] = 0; // La longitud del código del nodo raíz es 0

for (i = 2; i < 2*num; i++ )

heap[i] = heap[heap[i]] // La longitud del código del nodo es 0