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