我有两个二进制数组,一个大小为34(模式),另一个大小为10000(目标)。 我想看看目标中是否有任何具有阈值的模式(例如最多4个不匹配) 并返回匹配数(不发生叠加,如果一个匹配则下一个匹配将远离800个单元)。 我知道这是一种近似匹配问题,但我不知道使用哪种算法具有最佳性能。到目前为止我所做的事情:(方法2有更好的表现)
void compare (bool *target, int t, bool * pattern , int p , int threshold)
{
for(int i =0;i<t-p;i++){
if(like(target+i,pattern,p,threshold)){
return true;
}
}
return false;
}
void like2(bool *target, bool * pattern , int p , int threshold){
int k =0;
for(int i =0;i<p, ;i++){
k+= target[i] ^ pattern [i];
}
return (k<=threshold);
}
void like(bool *target, bool * pattern , int p , int threshold){
int k =threshold;
for(int i =0;i<p,k>=0 ;i++){
if(target[i]!=pattern[i]){
--k;
}
}
return (k >=0);
}
我尝试使用字符串匹配算法,例如Knuth-Morris-Pratt算法,但它们是完全匹配的,将它们更改为近似匹配算法是一种困难的方法。
答案 0 :(得分:3)
将模式组合成(长)整数pattern_int
,因为它只有34位。现在循环target
。在k = 0
,您将模式的target
位0-33组合到combined_int
。当您按照以下方式进入k + 1
重新计算combined_int
时:
combined_int = (combined_int << 1) & ~(1 << 34) | target[k + 34];
基本上,你将它移动一个位置(因为你从k
前进到k + 1
),清除不再有位并添加一个新位置。
查看匹配是否“足够接近”模式,XOR combined_int
与pattern_int
和计数1位。我相信后者是在现代CPU的单指令中完成的。
编辑:构建初始组合时,请确保pattern[0]
最终为pattern_int
中的最高位,同样为target
。否则,您需要更改combined_int
相应重新计算的方式。