快速字符串近似匹配的算法

时间:2013-05-03 04:35:00

标签: string algorithm

给定源字符串sn等长字符串,我需要找到一个快速算法来返回最多k个与源字符串不同的字符串每个相应位置s

这样做的快速算法是什么?

PS:我必须声称这是一个academic问题。如果可能,我想找到最有效的算法。

此外,我错过了一条非常重要的信息。 n等长字符串形成一个字典,将查询许多源字符串s。似乎有某种预处理步骤可以提高效率。

5 个答案:

答案 0 :(得分:2)

我的直觉就是迭代每个字符串n,维护一个与s不同的字符数的计数器,但我并没有声称它是最有效的解决方案。然而,这将是O(n)所以,除非这是一个已知的性能问题或学术问题,否则我会选择。

答案 1 :(得分:2)

答案 2 :(得分:1)

鉴于字符串是固定长度,您可以计算两个字符串之间的Hamming distance来确定相似性;这是字符串长度的O(n)。因此,最糟糕的情况是您的算法为O(nm),用于将字符串与m个字进行比较。

作为替代方案,快速解决方案也是一种记忆困难,就是将字典预处理成地图; keys是一个元组(p,c),其中p是字符串中的位置,c是该位置字符串中的字符,值是在该位置有字符的字符串(所以“the”将出现在地图中{(0,'t'),“the”},{(1,'h'),“the”},{(2,'e'),“the”})。要查询地图,请遍历查询字符串的字符并使用检索到的字符串构造结果映射; keys是字符串,values是从主映射中检索字符串的次数(因此使用查询字符串“the”,键“thx”的值为2,键“tee”将具有价值1)。最后,遍历结果映射并丢弃其值小于K的字符串。

您可以通过在结果映射完成时丢弃不可能等于K的键来节省内存。例如,如果K为5且N为8,那么当您到达查询字符串的第4到第8个字符时,您可以丢弃任何尚未包含在结果映射中的字符串,因为它们不可能具有5匹配字符。或者,当您完成查询字符串的第6个字符后,您可以遍历结果映射并删除值小于3的所有键。

如果需要,您可以将主要预先计算的地图卸载到NoSql键值数据库或沿着这些行的某些内容,以便保存在主内存中(并且还可以使您不必在每次程序时预先计算字典重新启动)。

不是将元组(p,c)存储为主映射中的键,而是将位置和字符连接成一个字符串(所以(5,'t')变为“5t”,并且(12, 'x')变为“12x”。

答案 3 :(得分:0)

在不知道每个输入字符串中匹配字符的位置的情况下,对于特定字符串,无论您检查它们的顺序如何,都可能需要检查每个字符。因此,只需迭代每个字符串字符, - 字符并保持不匹配总数的总和。如果i是到目前为止的不匹配数,则在false时返回i == k,并在字符串中剩余少于true个未检查字符时返回k-i。< / p>

请注意,根据字符串的长度以及允许的不匹配数量,迭代整个字符串而不是执行这些检查可能会更快,或者可能仅在每个字符后执行它们。玩弄它,看看你如何获得最快的表现。

答案 4 :(得分:0)

我的方法,如果我们大声思考:P我没有通过每个n字符串看不到这样做的方法,但我很高兴得到纠正。在此过程中,它将以预处理开始,以保​​存第二组n字符串,以便字符按升序排列。

比较的第一部分是检查每个n字符串,一次对n'中的每个字符ss'。{/ {} p>

如果s'小于n'则不等于并移至下一个s'。如果n'小于s',请转到下一个n'。否则记录匹配的字符。重复此操作,直到找到k未命中匹配项或找到其他匹配项,并相应地标记n

为了进一步考虑,可以对n中的每个相邻字符串进行添加的预处理,以查看不同字符的总数。然后可以在将字符串ns进行比较时使用,如果这些与相邻的n之间存在足够的差异,则可能不需要对其进行比较吗?