在C#中读取霍夫曼编码树

时间:2018-01-14 18:57:51

标签: c# loops tree doubly-linked-list huffman-code

我正在尝试构建一个可以从文本文件中读取字节并将其转换为霍夫曼代码的霍夫曼编码器。我需要能够解码。

到目前为止,我已经能够从文件中读取字节并将它们放在一个基于表示霍夫曼编码的双链表的树中。我有一个带有此文本的文本文件:" abcabcabd"。这是我生成的树:enter image description here

我的目标是读出树并将整个输出放在一个数组中。我期望的数组看起来像这样:"1, 01, 000, 1, 01, 000, 1, 01, 001"

唯一的问题是我不知道如何确定字母的位置。我想用1/0方法做到这一点。

所以我的问题是:如何确定'字节的位置?代码位于。我会在一段时间内完成吗?我希望它是可变的,因此创建一个库是不可能的。我试过这个:

首先我创建了我的树:

public static void mBitTree()
    {
        W = H;
        if (W.N != null)
        {
            int Fn = W.A;
            int Sn = W.N.A;
            int Cn = Fn + Sn;

            cZip n = new cZip(0, Cn);

            //First Set new node to link to subnodes.
            n.L = W;
            n.R = W.N;

            if (W.N.N != null)
            {
                n.N = H.N.N;
                H.N.N.P = n;
                H.N.N = n;
                //Safe and set new head and fix links.
                W = H.N.N;
                H.N.N = null;
                H.N.P = null;
                H.N = null;
                H = W;
            }
            //this means there were 2 nodes left. so the newly created one will become Head ant Tail and the tree is complete.
            else
            {
                H.N.P = null;
                H.N = null;
                H = n;
                T = n;
            }
        } 
        else
        {
            return;
        }
    }

我开始的顶部节点是H和T.它还有一个L和R. 需要检查的第一件事是H.L不等于当前。然后去H.R.L,然后去H.R.R.L等等。如果我有一个更大的文本文件,这也需要工作。所以我创建了这样的东西:

public static string[] mCodedchain(uint[] count, byte[] bytesInFile)
    {
        int counter = 0;                                                                
        for (int i = 0; i < count.Length; i++) { if (count[i] != 0) counter = counter + (int)count[i]; }
        string[] codedArray = new string[counter];


        for (int i = 0; i < bytesInFile.Length; i++)
        {
            int number = 0;
            while ((int)bytesInFile[i] != number )
            {
                number = H.L.V //and if not H.L Add R in between to go to H.R.L.V
            }               
        }            

        return codedArray;
    }

但是我不知道如何建立while循环。我已经尝试过很多东西,但这个东西似乎最有效,但是我无法让它发挥作用。

我不太确定这个问题是否清楚。但我希望是。

提前致谢,并且编码很快。

1 个答案:

答案 0 :(得分:1)

解码静态霍夫曼数据实际上非常简单。

你需要什么:

  • 带有符号的节点树(在您的情况下为字母/字节)附加在编码期间使用的相同配置
  • 一种从流中读取位的方法,一次一位

有了这个,这里是用于解码的伪代码:

<node> ← <root>
WHILE MORE
    <bit> ← <ReadBit()>
    IF <bit> IS 1 THEN
        <node> ← <node.LEFT>
    ELSE
        <node> ← <node.RIGHT>
    END IF
    IF <node.SYMBOL> THEN
        OUTPUT <node.SYMBOL> AS DECODED SYMBOL
        <node> ← <root>
    END IF
END WHILE

或者用简单的英语:

  

从根节点开始   从流中读取1位。如果该位为1,则转到当前节点的左子节点,否则转到右侧子节点。

     

每当你点击一个带有符号的节点时,输出符号并返回到根节点   返回“读取1位”并继续操作,直到您解码整个流

注意!您需要知道要分别输出多少个符号。这样做的原因是编码流中的最后一个字节可能有额外的位,如果你对它们进行解码,那么与编码前的原始数据相比,你可能会得到额外的符号。