KMP
K M P KMP KMP算法,又称模式匹配算法,能够在线性时间内判定字符串 A [ 1 → N ] A[1\to N] A[1→N]是否为字符串 B [ 1 → M ] B[1\to M] B[1→M]的子串,并求出字符串 A A A在字符串 B B B中各次出现的位置。
首先,有一个 O ( N M ) O(NM) O(NM)的暴力做法,尝试枚举字符串 B B B中的每一个位置 i i i,把字符串 A A A与字符串 B B B的后缀 B [ i → M ] B[i\to M] B[i→M]对齐,向后扫描逐一比较 A [ 1 ] A[1] A[1]与 B [ i ] B[i] B[i], A [ 2 ] A[2] A[2]与 B [ i + 1 ] B[i+1] B[i+1]…是否相等。我们把这种比较过程称为 A A A与 B B B尝试进行“匹配”。
如果你会字符串 H a s h Hash Hash,那么你就能自然地想到 H a s h Hash Hash也能做到在线性时间内求解。只需要检查字符串 A A A的 H a s h Hash Hash值与字符串 B B B的子串 A [ i − N + 1 → i ] A[i-N+1\to i] A[i−N+1→i]的 H a s h Hash Hash值是否相同。
K M P KMP KMP算法能够更高效、跟准确地处理这个问题,并且能为我们提供一些额外的信息。详细地讲, K M P KMP KMP算法分为两步。
KMP算法流程:
1.对字符串 A A A进行自我“匹配”,求出一个数组 n e x t next next,其中 n e x t [ i ] next[i] next[i]表示“ A A A中以 i i i结尾的非前缀(就是不包含此项)子串”与“ A A A的前缀”能够匹配的最长长度,即:
n e x t [ i ] = m a x ( j ) , 其中 j < i 并且 A [ i − j + 1 → i ] = A [ 1 → j ] next[i]=max(j),其中j<i 并且 A[i-j+1\to i]=A[1\to j] next[i]=max(j),其中j<i并且A[i−j+1→i]=A[1→j]
特别的,当不存在这样的 j j j时,令 n e x t [ i ] = 0 next[i]=0 next[i]=0;
2.对字符串A和字符串B进行匹配,求出一个数组f,其中f[i]表示“B中以i结尾的子串”与“A的前缀”能够匹配的最长长度即:
f [ i ] = m a x ( j ) 其中 j ≤ i 并且 B [ i − j + 1 → i ] = A [ 1 → j ] f[i]=max(j) 其中j\le i 并且B[i-j+1\to i]=A[1\to j] f[i]=max(j)其中j≤i并且B[i−j+1→