【问题标题】:searching bit-field templates (codebooks) [closed]搜索位域模板(码本)[关闭]
【发布时间】:2011-09-10 08:30:43
【问题描述】:

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

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

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

非常感谢...

阿克万

【问题讨论】:

  • 添加一个标签来表明你想使用哪种编程语言。许多人只通过他们的专业标签扫描帖子。祝你好运。
  • 已更新...感谢您的提示!

标签: c++ c search bitflags


【解决方案1】:

当然,虽然空间效率不是很高,但您当然可以预先计算所有 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]];

【讨论】:

  • 不幸的是我不能这样做,因为它会消耗太多的内存。这是进入具有 10K 总内存的设备的算法的一小部分......
  • @akevan:你能负担得起多少空间?你知道比特的分布吗? (它们是随机的吗?标准分布?码本中设置的 1 位是否多于 0 位?在模式中?)虽然......如果你只想要 a 答案(不是所有答案),你可以使用预先计算的 256 字节数组(或代替字节,将偏移量(字节)放入第一个匹配码字的码字数组中)
  • 好问题...它们的分布是随机的。我想码本包含几乎所有位模式的事实是有帮助的(并且还指向随机分布!),但我仍在试图弄清楚如何利用它。我有大约 500 个字的空间可供使用(24 位字)。
  • @akevan:嗯,正如我所说,你可以在 11 个单词的内存中获得第一个码本匹配。 u_int8_t 位模式[256]; ……;码本[位模式[输入]];
  • @Seth:感谢您提供的信息,非常有帮助。将继续努力 - 试图“提高”你的答案,但我不能,因为我没有声誉哈哈......不过谢谢!
【解决方案2】:

如果您只进行 8 位查找,那么预先计算所有答案然后将它们存储在 256 条目表中将是微不足道的。这样,您将获得持续时间查询,并且内存存储量仅为 256 个条目。

【讨论】:

  • Grr。抢我 41 秒。
  • 嗯,这是一个简单的问题 :) 无论如何都要投赞成票。
【解决方案3】:

一项优化可能是将代码存储在不同的存储桶中,具体取决于设置的位数。当您查找代码时,您只需查看 1/2 的代码(平均而言,如果代码分布均匀)。这是一个非常简单的优化,但算法的复杂度保持不变(O(n))。根据设置的位数对单个数组进行排序将使您能够进行类似的优化,而无需将代码存储在存储桶中。

旁注:我认为 200 是一个非常小的数字,我认为无论您如何优化它,线性方法的性能都不会有太大变化,除非您进行 大量 查找.但我猜这不是这个练习的重点......

【讨论】:

  • 嗯...我喜欢这个主意,但我仍然需要搜索所有存储桶。考虑到匹配的要求(模式必须与输入设置相同的位),如果我的输入为 0001 1100(设置 3 位),它将匹配 0011 1100(设置 4 位)、0111 1100(设置 5 位) ) 等。
  • @akevan:没错,我的错。
【解决方案4】:

如果我理解,您是说如果 response 只设置了 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);

【讨论】:

  • 感谢您的回复......但正如我最初的帖子所说:“我有一个标准的线性搜索,但当然效率很低。”我希望有一些关于如何在树或其他数据结构中构造数据以加快搜索速度的想法。
【解决方案5】:

我发布另一个答案是因为我有一个新的(更好的建议):

  1. 按值对码本进行排序
  2. 对于您要查找的每个代码,首先进行二进制下限搜索以找到第一个可能的匹配项(任何小于您正在查找的值都不能成为匹配项)
  3. 搜索从第一个可能匹配到最后一个元素的范围,看看是否有任何匹配。

该算法仍然是线性的,但是通过 O(log N) 查找来截断(希望)大多数值。查找小值仍然会很昂贵,查找大值会更便宜。

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

【讨论】:

  • 我不认为布隆过滤器有用。它会告诉我们是否设置了该位模式,但不会告诉我们使用了该位模式中的哪些值。由于 OP 说会看到大多数位模式,所以我没有看到好处。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-13
  • 2012-08-12
  • 2015-04-29
  • 1970-01-01
  • 2017-07-05
  • 2012-12-23
相关资源
最近更新 更多