【问题标题】:Reading the Huffman encoding tree in C#在 C# 中读取 Huffman 编码树
【发布时间】:2018-01-14 18:57:50
【问题描述】:

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

到目前为止,我已经能够从文件中读取字节并将它们放入基于表示 Huffman 编码的双链表的树中。我有一个带有此文本的文本文件:“abcabcabd”。这是我生成的树:

我的目标是读出树并将整个输出放入一个数组中。我预期的数组如下所示:"1, 01, 000, 1, 01, 000, 1, 01, 001"

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

所以我的问题是:如何确定“字节”代码的位置。我会在一个while循环中做吗?我希望它是可变的,因此不可能创建一个库。我试过这个:

首先我创建我的树:

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 循环。我已经尝试了很多东西,但这个似乎是最有效的,但我无法让它工作。

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

提前致谢,祝您编码愉快。

【问题讨论】:

  • 在这里查看我的答案:stackoverflow.com/questions/759707/…
  • @LasseVågsætherKarlsen 我已经找到了,但这不是我可以使用的东西,是吗?如果我立即将它们写入位,它确实解释了编码的工作原理等。并把它们读出来。但我试图将路径放入字符串数组中。因此,如果我错了,请纠正我,但是在这种情况下,您的答案中的代码示例没有用对吗?
  • 好的,那我被你的问题的标题弄糊涂了。
  • 当您开始从流中读取位时,从根节点开始,对于每个 0/1,您分别向右或向左。当你点击一个包含一个字母的节点,输出这个字母然后回到根节点,就是这么简单。
  • @LasseVågsætherKarlsen 啊,我明白了,谢谢。真的,我什至没有想过,但现在你再说一遍。你完全正确。

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


【解决方案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 位”并继续,直到您解码了整个流

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-07-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多