-
——>BF算法 点我·
BF算法时间复杂度比较高,下面介绍一种改进的模式匹配算法。KMP算法,可以在O(n+m)的时间数量级上完成串的模式匹配操作,每当匹配失败时,i 不用回溯,而是利用已经得到的“部分匹配”的结果将 j 向左移动一段距离,继续比较 S[i]==T[j] -
在BF算法中:
-
一趟
i=6
a b a b c a b c a c b a b
j=4
a b c a c
- 二趟
我们发现当 i=6,j=4 字符比较不相等时,又需要从 i=3,j=0 重新比较。仔细看看之后,i=3,j=0 和 i=4,j=0 和 i=5,j=0 的比较完全是不需要进行的。因为主串中的 i=3,4,5 的字符必然是 bca ,因为模式串的第一个字符为 a 不必在进行比较了,所以 i 不需要进行回溯,仅需将 j 向左移动到 j=1
i=6
a b a b c a b c a c b a b
j=1
a b c a c
这里有一个问题,**当失配时,模式串的 j 需要向左移动多远?
假设移动到模式串的第k个字符:
则主串 i 之前的 k 个字符 应与模式串 1 到 k 之前的字符相同
Si-k Si-k+1 Si-k+2 Si-1 = T0T1T2…Tk-1
部分匹配结果:
Si-k Si-k+1 Si-k+2 Si-1 = Ti-k Ti-k+1 Ti-k+2 Ti-1
得出:
T0T1T2…Tk-1 = Ti-k Ti-k+1 Ti-k+2 Ti-1
令 next[j] =k;求字符串前缀与后缀相等的最长长度
模式串 | a | b | a | b | a | b | c | a |
---|---|---|---|---|---|---|---|---|
j | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
next[j] | -1 | 0 | 0 | 1 | 2 | 3 | 4 | 0 |
为了方便 一般把 next[0]=-1
j=1 b字符前就一个字符a 没有后缀也没有前缀字符 next[1]=0
j=2 a字符前有字符ab ab前缀字符有a,后缀字符与b,a与b不相等 next[1]=0
j=3 b字符前有aba,aba前缀字符有a,ab,后缀有a,ba,a=a,最长长度为1,next[3]=1
j=4 字符abab前缀有a,ab,aba,后缀有bab,ab,最长长度为2,ab=ab,next[4]=2
代码实现:
public int IndexOfKMP(String S,String T,int pos){
char []a = S.toCharArray();
char []b = T.toCharArray();
int i=<