Huffman编码的解码

关于Huffman编码和KMP的知识请看我的这两篇文章:Huffman编码KMP

#include<bits/stdc++.h>
using namespace std;

/*
    Huffman解码:
        为什么把这个单独提出来,是因为我想把它和KMP结合起来使用。 
*/
class Node
{
    public:
        char c;         //被编码的字符 
        string code;    //字符的编码 
        int *next;      //编码的next数组 
};

int *getNext(string p)
{
    int l = p.length(), k = -1, i = 0;
    int *next = new int[l];
    next[0] = -1;
    while(i < l - 1)
    {
        while(k >= 0 && p[k] != p[i])
            k = next[k];
        i++;
        k++;
        if(p[i] == p[k])
            next[i] = next[k];
        else
            next[i] = k;
    }
    return next;
}
int KMPMatching(int *next, string p, string r)
{
    //在 p 中寻找 r 
    int i = 0, j = 0;   //i指向p,j指向r 
    int pl = p.length(), rl = r.length();
    if(pl < rl)
        return -1;
    while(i < pl && j < rl)
    {
        if(j == -1 || p[i] == r[j])
            i++, j++;
        else
            j = next[j];
    }
    if(j >= rl) //说明r被扫描完了,即找到匹配的了 
        return (i - rl);
    else
        return -1;
}
int main()
{
    /*
        不想把Huffman树的构建再复制一遍,所以直接使用了一些以编码的字符 
    */
    Node *arr = new Node[6];
    arr[0].c = 'c'; arr[0].code = "00";     arr[0].next = getNext(arr[0].code);
    arr[1].c = 'b'; arr[1].code = "01";     arr[1].next = getNext(arr[1].code);
    arr[2].c = 'd'; arr[2].code = "100";    arr[2].next = getNext(arr[2].code);
    arr[3].c = 'f'; arr[3].code = "1010";   arr[3].next = getNext(arr[3].code);
    arr[4].c = 'e'; arr[4].code = "1011";   arr[4].next = getNext(arr[4].code);
    arr[5].c = 'a'; arr[5].code = "11";     arr[5].next = getNext(arr[5].code);
    string str = "11010010010111010";
    int i = 0, j, l = str.length();
    while(i < l)
    {
        int flag = 0;
        for(j = 0; j < 6; j++)
        {
            int tl = arr[j].code.length();
            if(KMPMatching(arr[j].next, str.substr(i, tl), arr[j].code) == 0)
            {
                cout << arr[j].c;
                i += tl;
                flag = 1;
                break;
            }
        }
        if(flag == 0)
        {
            cout << "待解码的字符串有问题!";
            break;
        }
    }
    return 0;
}

/*  
    字符 权重 编码 
     c    4    00
     b    5    01
     d    3    100
     f    1    1010
     e    2    1011
     a    6    11
*/

猜你喜欢

转载自blog.csdn.net/qq_38206090/article/details/82314799