【问题标题】:Java loop and shiftingJava循环和移位
【发布时间】:2013-05-12 10:32:04
【问题描述】:

长话短说,我正在尝试从规范的霍夫曼列表中生成霍夫曼代码。本质上,应该运行以下两个循环,并生成一个二进制字符串。代码是:

for (int i = 1; i <= 17; i++) {
        for (int j = 0; j < input.length; j++) { 
            if (input[j] == i) {
                result.put(allocateCode(i, j), j); //update a hashmap
                huffCode += (1 << (17 - i)); //Update the huffman code
            }
        }

    }

基本上,代码应该查找所有长度为 1 的代码,并为每个代码生成一个霍夫曼代码。例如,1 的长度应该(按顺序):0、1。而 3 的长度应该是 100、101、110。

allocateCode 函数只是返回一个显示结果的字符串,第一次运行会产生这样的结果:

Huffman code for code 2 is: 0 (0) length was: 1
Huffman code for code 6 is: 10 (2) length was: 2
Huffman code for code 0 is: 1100 (12) length was: 4
Huffman code for code 3 is: 1101 (13) length was: 4
Huffman code for code 4 is: 1110 (14) length was: 4
Huffman code for code 7 is: 11110 (30) length was: 5
Huffman code for code 1 is: 111110 (62) length was: 6
Huffman code for code 5 is: 111111 (63) length was: 6

这是正确的,并且已经生成了正确的霍夫曼代码。但是,在第二个长度数组上运行它会产生这样的结果:

Huffman code for code 1 is: 0 (0) length was: 1
Huffman code for code 4 is: 1 (1) length was: 1
Huffman code for code 8 is: 100 (4) length was: 3
Huffman code for code 9 is: 100 (4) length was: 3
Huffman code for code 13 is: 101 (5) length was: 3
Huffman code for code 16 is: 1011000 (88) length was: 7
Huffman code for code 10 is: 10110001 (177) length was: 8
Huffman code for code 2 is: 101100011 (355) length was: 9
Huffman code for code 3 is: 101100011 (355) length was: 9
Huffman code for code 0 is: 1011001000 (712) length was: 10
Huffman code for code 5 is: 1011001000 (712) length was: 10
Huffman code for code 6 is: 1011001001 (713) length was: 10
Huffman code for code 7 is: 10110010011 (1427) length was: 11
Huffman code for code 14 is: 10110010011 (1427) length was: 11
Huffman code for code 17 is: 10110010100 (1428) length was: 11
Huffman code for code 19 is: 10110010100 (1428) length was: 11
Huffman code for code 18 is: 101100101010000 (22864) length was: 15

如您所见,多次生成相同的代码,示例为代码 8 和 9,以及代码 2 和 3。

我认为我的问题在于嵌套循环,但我无法弄清楚为什么它在一次运行中完美运行,而在另一次运行中失败。

我可能只是遗漏了一些明显的东西,但我看不到它。

任何建议将不胜感激。

谢谢

更新

回顾我的代码后,我似乎在首先读取数据时犯了一个小错误,因此我得到了不正确的霍夫曼代码!

【问题讨论】:

  • 您正在随时更新代码。霍夫曼代码根据您已经看到的值进行更改是正常的。您遇到的另一个问题是无法知道您的价值观在哪里停止,例如是1011000 4144111 或 581
  • 我不太清楚你的意思彼得?我必须承认我仍然对霍夫曼代码感到有些困惑。你能详细说明一下吗?
  • 我假设您提前生成了霍夫曼代码,或者您的问题没有意义。通常在处理每个符号时更新霍夫曼代码。这意味着一个代码,它意味着一个符号以后可以表示不同的符号。
  • 我生成的代码来自存储在已压缩流中的规范列表。我只是想找出正确的代码,然后存储它。上面显示的两个示例中的每一个都来自两个不同的规范列表。我想我越来越困惑了:)
  • 我确实看到了。我有一种感觉,我一开始就读错了数据。我得回去看看我的输入法。谢谢彼得。

标签: java loops binary bit-shift huffman-code


【解决方案1】:

第二个示例中的前两个代码的长度均为 1,在前两个代码之后没有其他可能的代码。所有前缀模式都已用完。

您的代码应保留可用剩余代码的计数,以检测错误输入。只需减少每个代码的计数,每次向上移动到比当前长度多一倍的下一个长度时,将计数加倍。 (即使没有该长度的代码,也要确保加倍,例如,如果您从长度为 3 的代码移动到长度为 5 的代码,即使没有长度为 4 的代码,也要加倍计数。)从两个开始计数长度为一的代码。

如果该计数变为负数,则说明您有错误,您可以立即停止。无法为该组长度分配代码。

如果在进程结束时计数不为零,那么您的代码不完整。根据您的应用程序,这可能是也可能不是错误。这意味着代码不是最优的,并且可以使用更少的位来对这些符号进行编码。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-05-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-07
    相关资源
    最近更新 更多