【问题标题】:Identifying the positions of characters in Huffman Coding Algorithm识别霍夫曼编码算法中的字符位置
【发布时间】:2012-05-24 05:17:11
【问题描述】:

我正在阅读 Huffman Coding Algorithm 来对字符串进行编码。我可以看到制作一棵树时考虑了字符的频率。

这是频率表:

a   b   d   e   f   h   i   k   n   o   r   s   t   u   v 
5   1   3   7   3   1   1   1   4   1   5   1   2   1   1   9

*space has frequency 9

我可以看到有一棵树是用这个做的。但我无法推导出如何在树中放置元素的规则。

书上说所有频率较高的字符都应该靠近词根。但是如果两个以上的字符频率相同,那么它们必须位于词根的不同侧。

问题是,我们如何决定位置?

在我的书中a 有代码010r011e 有代码100

有人可以帮忙吗?

【问题讨论】:

    标签: java algorithm compression huffman-code


    【解决方案1】:

    你试过Wikipedia吗?有一个关于霍夫曼编码的很好的演示。算法很简单:你需要一个priority queue

    算法有点像这样:

    1. Create tree nodes with each character and their frequencies
    2. Put all the letters and their frequencies in a priority queue Q
    3. Do until Q contains only one element:
        3a. Pick two lowest-frequency items a, b
        3b. Create a tree node z with frequency(z) = frequency(a) + frequency(b)
        3c. Add a and b as left and right children of z
        3d. Put z in Q
    4. Pick up the only element from Q. This would be the root of the tree.
    5. Assign binary codes to each leaf node according to their root-to-leaf path.
    

    优先级队列应该设计成最小优先级队列,即频率最低的节点应该最先出来。对于处理相同频率的项目,使用一些其他标准(例如字母顺序)作为决胜局。与编码和解码的平局标准保持一致。

    【讨论】:

    • 我不认为你有这个问题。他已经知道如何制作这棵树了。他想知道如何将 0 和 1 分配给分支。
    • 阅读问题:“但我无法推导出如何在树中放置元素的规则。
    • 阅读问题(他甚至说:问题是):“但如果两个以上的字符频率相同,那么它们必须位于根的不同侧。问题是,我们如何决定位置?"
    • 我已经在回答的最后指出了这一点。
    • 您的 #5 并没有说明将 0 分配给哪个并排的叶子中的哪一个以及将 1 分配给哪个。你可以去任何一种方式。最初的问题是如何决定。
    【解决方案2】:

    一旦你有了你的树,你就可以随意选择如何将 0 和 1 分配给道路每个岔路口的两个分支。因此,如果没有办法使该分配规范化,那么如何将位分配给每个符号就没有“正确答案”,例如r 必须是 011r 可以是任何三位值。 (尽管这组频率的长度必须是 3 位。)

    重要的是解码器获得与编码器相同的 0 和 1 分配。您可以直接发送代码,也可以发送长度并以规范的方式分配 0 和 1。例如,在 zip、gzip、png 等中使用的压缩算法仅发送每个符号的位数。然后从最小长度开始,为该长度的所有符号分配从 0 开始的代码。符号按顺序分配代码,符号按其表示整数排序。例如。字符的 ASCII 排序顺序。对于下一个长度,在右侧添加位并且代码计数继续。这保证了正确的前缀码,从左到右解码。

    所以在这种情况下,代码长度是:

    2: _
    3: a, e, r
    4: d, f, n
    5: b, h, t
    6: i, k, o, s, u, v
    

    所以我们得到(每个长度内的符号按字母顺序排列):

    _: 00
    a: 010
    e: 011
    r: 100
    d: 1010
    f: 1011
    n: 1100
    b: 11010
    h: 11011
    t: 11100
    i: 111010
    k: 111011
    o: 111100
    s: 111101
    u: 111110
    v: 111111
    

    这里的位分配与书中三个符号中的两个不同。作为其他非常好的规范前缀代码选择的示例,您可以反转所有位,或者您可以反转位列的任何子集。例如。您可以反转整个第一列。您可以更改每个长度的符号顺序。您可以颠倒位顺序。事实上,zip等都是以相反的顺序存储上面显示的位,因此解码是从最低有效位开始进行的,即从右到左。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-17
      • 1970-01-01
      • 2018-03-02
      • 1970-01-01
      相关资源
      最近更新 更多