C++ 用面具搜索

C++ 用面具搜索,c++,c,algorithm,search,mask,C++,C,Algorithm,Search,Mask,存在具有以下类型的大型条目数组: typedef struct { int value; int mask; int otherData; } Entry; 我想根据提供的int键在这个数组中查找一个条目尽可能快。需要输入以确保(键和掩码)=值 这种阵列组织的最佳方式是什么?相应的算法是什么 编辑:数组组织没有限制;它是静态的,可以在查找之前准备。值和掩码可以具有任意值 Edit2:value和mask可以具有任意值,但数组中的条目数约为10000。因此,某些“模式”可

存在具有以下类型的大型条目数组:

typedef struct {
    int value;
    int mask;
    int otherData;
} Entry;
我想根据提供的
int键在这个数组中查找一个条目尽可能快。需要输入以确保
(键和掩码)=值

这种阵列组织的最佳方式是什么?相应的算法是什么

编辑:数组组织没有限制;它是静态的,可以在查找之前准备。
掩码
可以具有任意值

Edit2:
value
mask
可以具有任意值,但数组中的条目数约为10000。因此,某些“模式”可以提前计算


查找的数量很大。

因为没有额外的信息(例如,数组已排序),所以需要进行线性搜索-遍历数组并检查条件-伪代码:

for( size_t index = 0; index < arraySize; index++ ) {
   if( ( array[index].mask & key ) == array[index].value ) ) {
      return index;
   }
}
return -1;
for(size\u t index=0;index
  • 如果您有一个条目的键映射,那么这将非常容易

  • 若数组是按键排序的,那个么只需稍加努力就可以进行字典二进制搜索。[事实上,也许不是!]

  • 实际上,您只需遍历数组,直到找到要查找的内容为止。也就是说,从开始到结束迭代,并在找到它时停止


顺便说一句,这是一个很好的例子,说明了数据结构的选择如何影响后续算法的可用性。如果你一开始就选择了错误的数据结构,你就不能仅仅用算法来解决问题

线性搜索当然可以,但是如果需要使用同一个键进行多次查找,可以尝试首先根据
(键和掩码)
对范围进行排序。如果你只有几个固定键,你可以尝试使用一个,每个键值有一个索引。

如果
掩码对每个条目任意变化,我看不到太多
线性搜索的替代方法。如果存在重大的限制条件
屏蔽
,这样只有几个值是可能的,最好 对
掩码
的每个值使用某种类型的
映射
,进行线性搜索 要查找第一个包含您要查找的值的
映射
。 或者,如果
掩码
s仅涉及少数位,则它可能值得 使用
多重映射
,按
值排序
,并用所有
掩码
s,并用
键索引
处理相同的操作,然后是线性
使用完整的
进行搜索,以找到精确的匹配项

每个位都是独立的,因此在预处理阶段[*]您可以将每个条目分类32次(或无论
int
的大小)。每个分类存储2个集合:当
为0时在该位匹配的集合和当
为1时匹配的集合

也就是说,如果该位的值==1且掩码==0,则该分类根本不存储该条目,因为它与
键的任何值都不匹配(事实上,无论您使用何种方案,在任何预处理阶段都应删除此类条目,因此即使有一位是这样的,也不应存储任何分类条目)。如果两者都为0,则存储到两个集合中。否则存储到两个集合中的一个集合中

然后,给定密钥,您希望找到32个集合的快速交集

根据原始数组的大小,存储每个集合的最佳方式可能是一个巨大的位数组,指示数组中的每个条目是否在集合中。然后可以一次查找一个字-
&
共32个字,每个位数组一个字。如果结果为0,则继续。如果结果为非0,则有一个匹配项,并且结果中设置的位告诉您哪个条目是匹配项。当然,这在数组的大小上仍然是线性的,事实上,您正在执行31个
&
操作来检查32个条目是否匹配,这与通过原始数组进行简单的线性搜索大致相同。但是比较和分支更少,而且您查看的数据更为压缩,因此您可能会获得更好的性能

或者可能有更好的方法来进行交叉

如果键倾向于重复使用,则应在从键到条目的映射中缓存查找结果。如果可能的键的数量相当少(即,如果可能的输入键明显少于2^32个,和/或您有大量可用内存),则预处理阶段可能只是:

  • 依次记下每个条目
  • 找出它匹配的可能键
  • 将其添加到这些关键点的地图中

  • [*]在没有任何预处理的情况下,显然您所能做的就是检查每个数组成员,直到找到匹配项或检查完所有内容。

    如果掩码中的零位数很小,您可以为掩码中的每个“不在乎”位复制条目。例如,如果
    value=0
    mask=0xfffe
    ,则在表中输入
    key=0
    key=1
    。对于
    value=0
    mask=0xfeef
    ,在表中输入4项:
    key=0x0000
    key=0x0010
    key=0x0100
    key=0x0110
    。现在,您可以对条目进行排序并使用二进制搜索,或者使用二进制搜索结构,例如
    std::map

    是否可以保证给定密钥的数组中只有一个条目?对密钥和掩码是否有任何限制?如果没有某种限制,只有线性搜索才有意义。另外,对数组组织没有限制。例如,它可以被排序。
    找到应用的第一个条目就足够了