有人能告诉我在java中使用可变长度位串解码二进制数据的最佳方法吗?
例如:
二进制数据为10101000 11100010 01100001 01010111 01110001 01010110
我可能需要找到以下任何一个01,100,110,1110,1010的第一场比赛...
在这种情况下匹配将是1010.然后我需要对剩余的二进制数据执行相同的操作。位串最长可达16位,并跨越字节边界。
基本上,我正在尝试使用我从头文件中的Huffman表创建的位字符串来解码jffgs。我可以做到,只是它非常混乱,我将所有内容,包括二进制数据,首先转换为Stringbuffers,我知道这不是正确的方法。
在我将所有内容加载到字符串缓冲区之前,我尝试仅使用二进制数字,但当然我不能忽略像00011这样的代码中的前导0。我敢肯定必须有一些聪明的方法使用位运算符和喜欢这样做,但我一直盯着解释位掩码和左移等的页面,我仍然没有线索!
非常感谢您的帮助!
编辑:
感谢所有建议。我已经采用二叉树方法,因为它似乎是霍夫曼的标准方式。真的很有意义,因为霍夫曼代码是使用树创建的。我还将研究存储我需要搜索的二进制数据的大整数。不知道如何将多个答案标记为正确,但感谢所有相同的。
答案 0 :(得分:4)
您可能会使用消耗0和1的状态机。状态机将具有您要检测的所有模式的最终状态。每当它进入最终状态之一时,就会使用匹配的模式向您发送消息并返回初始状态。
最后,您只有一台DAG形式的状态机,其中包含您的所有模式。
要实现它,请使用状态模式(http://en.wikipedia.org/wiki/State_pattern)或状态机的任何其他实现。
答案 1 :(得分:3)
由于您要解码霍夫曼编码数据,您应该创建一个二叉树,其中叶子将解码的位串保存为数据,每个霍夫曼代码的位是相应数据的路径。通过位移和位掩码操作来访问霍夫曼码的位。当你到达一个叶子时,你输出该叶子的数据并返回到树的根。它非常快速有效。
答案 2 :(得分:1)
您可以尝试将其填充到BigInteger中,然后使用shift和test方法。然后使用循环来遍历并接受每个子模式。
如果霍夫曼代码在树中,1 ==右节点,0 ==左节点。
for( int i =numbitsTotal; i > 0; --i )
{
int bit = bigInt.testBit( i );
if( bit == 1 )
{
// take right node -- if null accept code, apply from top
}
else
{
// take left node -- if null accept code, apply from top
}
}
答案 3 :(得分:1)
我建议trie。它明确地设计用于前缀搜索。在你的情况下,它将是一个二进制trie。
答案 4 :(得分:0)
您可以使用java.util.BitSet来存储二进制数据,然后您可以实现一些搜索函数来查找较大的BitSet中较小BitSet的位置...