performance - 找到到任何子串的最小汉明距离的最快方法?

标签 performance algorithm string

给定一个长字符串L和一个较短的字符串S(约束条件是L.length必须>= S .length),我想找到 S 和长度等于 SL 的任何子字符串之间的最小汉明距离。长度。让我们调用此 minHamming() 的函数。例如,

minHamming(ABCDEFGHIJ, CDEFGG) == 1

minHamming(ABCDEFGHIJ, BCDGHI) == 3

以显而易见的方式(枚举 L 的每个子串)需要 O(S.length * L.length) 时间。有什么聪明的方法可以在次线性时间内做到这一点吗?我用几个不同的 S 字符串搜索相同的 L,所以对 L 进行一些复杂的预处理是可以接受的。

编辑:修改后的 Boyer-Moore 是个好主意,除了我的字母表只有 4 个字母 (DNA)。

最佳答案

也许令人惊讶的是,使用快速傅里叶变换 (FFT),这个确切的问题可以在 O(|A|nlog n) 时间内解决,其中 n 是较大序列的长度 L|A| 是字母表的大小。

这是唐纳德·本森 (Donald Benson) 描述其工作原理的一篇论文的免费 PDF 文件:

总结:将每个字符串 SL 转换为多个指示器向量(每个字符一个,所以 4 在 DNA 的情况下),然后是 convolve相应的向量以确定每个可能对齐的匹配计数。诀窍在于,通常需要 O(n^2) 时间的“时间”域中的卷积可以使用“频率”域中的乘法来实现,这只需要 O(n) 时间,加上转换所需的时间域之间并再次返回。使用 FFT 每次转换仅需 O(nlog n) 时间,因此整体时间复杂度为 O(|A|nlog n)。为了获得最快的速度,使用了有限域 FFT,它只需要整数运算。

注意:对于任意SL,此算法显然比直接的 O(mn) 算法具有巨大的性能优势,因为 |S||L| 变大了,但是 OTOH 如果 S 通常比 log|L| 短(例如当查询具有小序列的大型数据库时),那么显然这种方法没有提供加速。

2009 年 7 月 21 日更新:更新后提到时间复杂度也线性取决于字母表的大小,因为必须为字母表中的每个字符使用一对单独的指示向量.

关于performance - 找到到任何子串的最小汉明距离的最快方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33557060/

相关文章:

performance - 庞大服务器/服务器集群的Elasticsearch模糊匹配优化

javascript - 如何区分时间字符串和非时间字符串

c++ - 指针赋值与指针运算

Sql Server 查询性能

MATLAB 中自然语言处理的性能问题

c++ - 以 cv::Point 为键的 std::map

algorithm - 为什么冒泡排序是 O(n^2)?

javascript - 将一个数组与另一个数组进行比较,以确保第二个数组不包含不同的值

string - 在错误消息中包含数据的惯用方法是什么?

string - 为什么我的 Groovy println 在正确的语句后总是返回 null?