简而言之,我试图从规范的霍夫曼列表中生成霍夫曼代码。本质上,应该运行以下两个循环,并生成二进制字符串。代码是:
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&amp; 9,代码2&amp; 3.
我认为我的问题在于嵌套循环,但我无法弄清楚为什么它在一次运行中完美运行,而在另一次运行时失败。
我可能只是遗漏了一些明显的东西,但我看不到它。
非常感谢任何建议。
由于
更新
通过我的代码后,看起来我在读取数据时实际上犯了一个小错误,因此我得到了不正确的霍夫曼代码!!
答案 0 :(得分:1)
第二个示例中的前两个代码都有一个长度,在前两个代码之后不会留下其他可能的代码。所有前缀模式都已用完。
您的代码应保留可用剩余代码的计数以检测错误输入。只需递减每个代码的计数,并在每次向上移动到当前长度的下一个长度时将计数加倍。 (即使没有该长度的代码,也要确保加倍,例如,如果从长度为3的代码移动到长度为5的代码,则长度为4的代码的计数加倍,即使没有。)以2开始计数长度为一码。
如果该计数变为负数,则表示您有错误,您可以在那里停下来。无法将代码分配给该组长度。
如果在流程结束时计数不为零,那么您的代码不完整。根据您的应用程序,这可能是也可能不是错误。这意味着代码不是最优的,并且可以使用更少的比特来编码这些符号。