搜索位域模板(代码簿)

时间:2011-06-07 19:14:17

标签: c++ c search linear bitflags

我在码本中有一堆8位值(大约200个)。

我的程序将生成一个8位值以响应输入,我需要找到码本中具有相同位设置的匹配的所有(甚至第一个是有用的)。未设置的位无关紧要。

您能想到a)存储和b)搜索码本以查找所有匹配的最佳方式吗?我有一个标准的线性搜索,但当然效率很低。

非常感谢......

akevan

5 个答案:

答案 0 :(得分:2)

当然,虽然空间效率不是很高,但您当然可以预先计算所有256位模式的匹配项。您将拥有256个列表的数组,每个列表将包含代码集中的每个代码,并设置这些位。

您可以以256个字节(11个字的内存)获得第一个匹配。

初​​始化:

u_int8_t bitpatterns[256];
memset(bitpatterns,0,sizeof(bitpatterns));

for(x=sizeof(codebook)-1;x>=0;x--)
  for(y=0;y<256;y++)
    if (y&codebook[x] == y)
      bitpatterns[y] = x;

查找

codeword = codebook[bitpatterns[input]];

答案 1 :(得分:1)

一种优化方法可能是根据设置的位数将代码存储在不同的存储区中。当你查找代码时,你只需要查看1/2的代码(平均来说,如果代码是均匀分布的)。这是一个非常简单的优化,但算法的复杂性保持不变(O(n))。根据设置的位数对单个数组进行排序,可以让您进行类似的优化,而无需将代码存储在存储桶中。

旁注:我认为200是一个非常小的数字,我不认为你会看到线性方法的性能变化,无论你如何优化它,除非你做很多的查找。但我猜这不是这个练习的重点......

答案 2 :(得分:1)

如果您只进行8位查找,那么预先计算所有答案然后将它们存储在256个条目表中将是微不足道的。这样你就可以得到恒定的时间查询,而内存存储只有大约256个条目。

答案 3 :(得分:0)

如果我理解,您说如果响应仅设置了1,3,5位,那么您希望 codebook 中的所有代码都有标记1, 3,5集,你不关心位2,4,6,7,8。

如果是这样,这是你的伪代码:

matchingCodes = new List<Code>
foreach(code in codebook)
    if((response & code) == response) matchingCodes.add(code);

答案 4 :(得分:0)

我发布了另一个答案,因为我得到了一个新的(更好的建议):

  1. 按值对代码簿进行排序
  2. 对于您正在查找的每个代码,首先执行二进制下限搜索以查找第一个可能的匹配(任何小于您查找的值都不能匹配)
  3. 搜索第一个可能匹配的范围,直到最后一个元素,以查看是否有任何匹配。
  4. 算法仍然是线性的,但是使用O(log N)查找来截断(希望)大多数值。查看小值仍然很昂贵,查找大值会更便宜。

    您还可以 使用Bloom filter进行初始搜索以切断大多数情况,并对其余情况进行线性搜索。过滤器可能有误报,因此当过滤器返回true时,您必须进行线性搜索。此数据结构要求您具有大量独立散列函数(例如,基于设置的位数,所有设置位的乘积,奇数与偶数,数字本身等)。如果您希望偶尔找到代码(如果过滤器返回false,则保证代码不在代码簿中),这可能是一个很好的优化。但是,我怀疑这比实际优化更具理论意义。