La implementación de C ++ utiliza el método de codificación de Huffman para realizar la codificación y decodificación de caracteres de comunicación (árbol de Huffman)

Tema: Utilice el método de codificación de Huffman para realizar la codificación y decodificación de caracteres de comunicación.

Imagen de efecto:

  • Ingrese el código de cadena original para implementar HuffmanTree
    Inserte la descripción de la imagen aquí
  • Ingrese pesos para implementar HuffmanTree
    Inserte la descripción de la imagen aquí
  • Puede ingresar números, caracteres, espacios y símbolos al mismo tiempo

Inserte la descripción de la imagen aquí

Ideas:

  • ①: Primero, para construir HuffmanTree, necesitamos procesar los pesos de los caracteres de entrada. Aquí, dado que el método de entrada principal es la cadena de entrada, la función correspondiente se usa para calcular el peso de cada carácter o ingresar directamente Hay dos formas para el peso de cada carácter, y los métodos de procesamiento correspondientes son ligeramente diferentes, pero generalmente son los mismos. Definí una matriz de peso de tipo doble para almacenar el peso del carácter, y luego definí una matriz de código para almacenar Cada carácter no repetido puede resolver el problema de que cuando el usuario ingresa una cadena, incluso si hay una gran cantidad de caracteres repetidos, se puede calcular el peso correcto. Una vez obtenido el peso completo, podemos comenzar a construir HuffmanTree.
  • ② Primero, establecemos el número correspondiente de nodos HuffmanTree según el tamaño de la matriz de código, y al mismo tiempo inicializamos estos nodos, y luego establecemos una cola de prioridad q del tipo de nodo HuffmanTree, y procedemos de pequeño a grande según el peso del nodo Clasificación interna, a fin de prepararnos para nuestra próxima construcción formal de HuffmanTree Cada vez que sacamos los dos primeros elementos en q y los fusionamos, nos damos cuenta de que cada nodo fusionado es el nodo con el menor peso. Fusionar, y luego colocamos el nodo combinado de los dos nodos en la cola q nuevamente, y hacemos un bucle hasta que solo quede un nodo raíz de elemento en q, de modo que se construya un árbol HuffmanTree.
  • ③Después de construir el árbol HuffmanTree, podemos usar la función recursiva para atravesar el árbol Huffman. El propósito de esto es imprimir el código de cada carácter. Al mismo tiempo, también podemos simular el árbol HuffmanTree para imprimir el peso de cada nodo, por lo que Puede ver la construcción interna de HuffmanTree de forma más intuitiva.
  • ④ El proceso de decodificación solo necesita atravesar el árbol HuffmanTree de acuerdo con el texto cifrado de entrada, comenzando desde el nodo raíz y el primer bit del texto cifrado, si el bit actual es '0', el nodo actual cambia del nodo raíz al nodo raíz Si el bit actual es '1', entonces el nodo actual cambiará del nodo raíz al nodo derecho del nodo raíz, por lo que hasta que el nodo raíz no tenga nodos izquierdo y derecho, guardaremos los caracteres en este nodo. Después de la impresión, se realiza la decodificación de un carácter. Si desea continuar decodificando, solo necesita actualizar el nodo actual de nuevo al nodo raíz original.

Código:

#include <stdio.h>
#include<windows.h>
#include<string.h>
#include<stdlib.h>
#include<iostream>
#include<algorithm>
#include<vector>
#include<string>
#include<queue>
using namespace std;
vector<char> code;
double weight[256];
int n;    
typedef struct HuffTree
{
    
    
    string code;
    char symbol;
    double weight;
    HuffTree* lchild;
    HuffTree* rchild;
} Node,*Nodeptr;
struct cmp
{
    
    
    bool operator()(Nodeptr & a, Nodeptr & b)
    {
    
    
        return a->weight > b->weight;
    }
};
priority_queue<Nodeptr, vector<Nodeptr>, cmp>q;
void codework()
{
    
    
    cout << "----------欢迎使用霍夫曼树---------" << endl;
    cout << "请选择输入字符串原码或者输入权值:" << endl;
    cout << "1.输入原码 2.输入权值" << endl;
    int x;
    cin >> x;
    char ch=getchar();
    system("cls");
    switch (x)
    {
    
    
    case 1:
        {
    
    
        string s;
        cout << "请输入原码:";
        getline(cin, s);
        for (int i = 0; i < s.size(); i++)
        {
    
    
            if (count(code.begin(), code.end(), s[i]) == 0)
                code.push_back(s[i]);
            weight[s[i]]++;
        }
        }
        break;
    case 2:
        {
    
    
            int num;
            cout << "请输入要输入多少个字符:";
            cin >> num;
            for (int i = 0; i < num; i++)
            {
    
    
                getchar();
                char x;
                double y;
                cout << "请输入第" << i + 1 << "个字符" ;
                x = getchar();
                cout << "请输入第" << i + 1 << "个字符的权值";
                cin >> y;
                if (count(code.begin(), code.end(), x) == 0)
                code.push_back(x);
                weight[x]= y;
            }
           
        }
        break;
    }
}
void PrintHuffmanTree(Nodeptr root)
{
    
    
    cout << root->weight;
    if (root->lchild != NULL || root->rchild != NULL)
    {
    
    
        cout << "(";
        PrintHuffmanTree(root->lchild);
        cout << ",";
        PrintHuffmanTree(root->rchild);
        cout << ")";
    }
}
Nodeptr CreatHuffmanTree()
{
    
    
    codework();
    n = code.size();
    for (int i = 0; i <n; i++)
    {
    
    
        Nodeptr CurNode = new Node;
        CurNode->symbol = code[i];
        CurNode->weight = weight[code[i]];
        CurNode->lchild = NULL;
        CurNode->rchild = NULL;
        q.push(CurNode);
    }
    for (int i = 1; i <= n - 1; i++)
    {
    
    
        Nodeptr x1 = q.top();
        q.pop();
        Nodeptr x2 = q.top();
        q.pop();
        cout << "第" << i<< "次: 取出的左节点x1权值为" << (double)x1->weight << "   取出的右节点x2权值为:" << (double)x2->weight <<" 它们的父节点权值为:"<< (double)(x1->weight + x2->weight) << endl;//zrz 2020.5.20
        Nodeptr NewNode = new Node;
        NewNode->symbol = 0;
        NewNode->weight = x1->weight + x2->weight;
        NewNode->lchild = x1;
        NewNode->rchild = x2;
        q.push(NewNode);
    }
     PrintHuffmanTree(q.top());
     cout << endl;
     return q.top();
}
void Coding(Nodeptr root,string code)
{
    
    
    if (root->lchild == NULL && root->rchild == NULL)
    {
    
    
        root->code = code;
        cout << root->symbol << "的编码为:" << root->code << endl;
        return;
    }
    if (root->lchild != NULL)
    {
    
    
        code +='0';
        Coding(root->lchild, code);
        code = code.substr(0, code.size() - 1);
    }
    if (root->rchild != NULL)
    {
    
    
        code += '1';
        Coding(root->rchild, code);
        code = code.substr(0, code.size() - 1);
    }

}
void Decodeing(Nodeptr root)
{
    
    
    string s, Ciphertext, Plaintext;
    cout << "请输入要解码的字符串:";
    cin >> s;
    Nodeptr temp = root;
    for (int i = 0; i < s.size(); i++)
    {
    
    
        
        if (s[i] == '0')
        {
    
    
            if (temp->lchild != NULL)
            {
    
    
                Ciphertext += '0';
                temp = temp->lchild;
            }
        }
        else if (s[i] == '1')
        {
    
    
            Ciphertext += '1';
            if (temp->rchild != NULL)
            {
    
    
                temp = temp->rchild;
            }
        }
        if (temp->lchild == NULL && temp->rchild == NULL)
        {
    
    
            Ciphertext += ' ';
            Plaintext += temp->symbol;
            temp = root;
        }
    }
    for (int i = 0; i < Ciphertext.size(); i++)
        cout << Ciphertext[i];
    cout << endl;
    for (int i = 0; i < Plaintext.size(); i++)
        cout << Plaintext[i];
    cout << endl;
}
void DestroyHuffmanTree(Nodeptr root)
{
    
    
     if (root->lchild != NULL)
         DestroyHuffmanTree(root->lchild);
     if (root->rchild != NULL)
         DestroyHuffmanTree(root->rchild);
     delete(root);
}
int main()
{
    
    
    Node* root= CreatHuffmanTree();
    Coding(root, "");
    Decodeing(root);
    DestroyHuffmanTree(root);
    return 0;
}

Supongo que te gusta

Origin blog.csdn.net/qq_43663263/article/details/106253163
Recomendado
Clasificación