如何最好地搜索可变长度位串的二进制数据?

时间:2009-03-17 21:50:46

标签: java jpeg huffman-code

有人能告诉我在java中使用可变长度位串解码二进制数据的最佳方法吗?

例如:

  

二进制数据为10101000 11100010 01100001 01010111 01110001 01010110

     

我可能需要找到以下任何一个01,100,110,1110,1010的第一场比赛...

     

在这种情况下匹配将是1010.然后我需要对剩余的二进制数据执行相同的操作。位串最长可达16位,并跨越字节边界。

基本上,我正在尝试使用我从头文件中的Huffman表创建的位字符串来解码jffgs。我可以做到,只是它非常混乱,我将所有内容,包括二进制数据,首先转换为Stringbuffers,我知道这不是正确的方法。

在我将所有内容加载到字符串缓冲区之前,我尝试仅使用二进制数字,但当然我不能忽略像00011这样的代码中的前导0。我敢肯定必须有一些聪明的方法使用位运算符和喜欢这样做,但我一直盯着解释位掩码和左移等的页面,我仍然没有线索!

非常感谢您的帮助!

编辑:

感谢所有建议。我已经采用二叉树方法,因为它似乎是霍夫曼的标准方式。真的很有意义,因为霍夫曼代码是使用树创建的。我还将研究存储我需要搜索的二进制数据的大整数。不知道如何将多个答案标记为正确,但感谢所有相同的。

5 个答案:

答案 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的位置...