KMP算法的图解:http://blog.csdn.net/u010232171/article/details/41945605
图解中的减法操作与下面的伪代码不同,应该以下面的代码为准
KMP算法的next数组求解:http://blog.csdn.net/u010232171/article/details/41961837
下面的伪代码出自《算法引论—— 一种创造性方法》,作者Udi Manber,第六章的6.7小节(多读书真的可以扩宽知识面,好的解或许就在其中)
算法 String_Match(A, n, B, m)
输入:A(长度为n的字符串)和B(长度为m的字符串), A是原串,B是模式串
输出:Start(B在A中第一次出现的下标,即使得B是A中从A[start]开始的子串的第一个下标)
注意:数组的下标从1开始
时间复杂度O(n)
Begin
i = 1, j =1, start = 0;
while start == 0 and i <= n do
if B[j] == A[i] then
j = j + 1;
i = i + 1;
else
j = next[j] + 1;
if j == 0 then
j = 1;
i = i + 1;
end if;
end if;
if j == m + 1 then
start = i – m;
end if;
end while;
End;
———————————————————————————————————————————————————-
KMP算法中的next数组从下面的程序中得到。。。。。
算法 Compute_Next(B, m)
输入:B(长度为m的字符串)
输出:next(大小为m的数组)
注意:B和next的下标都是从1开始
next数组的意义:next[i] = max( j | B(1 to j) == B(i-j, to i-1), 0 < j < i-1 ),即B与A在i处出现字符不相等时,B向右移动的最大距离。
时间复杂度:O(m)
Begin
next[1] = -1;
next[2] = 0;
for i = 3 to m do
j = next[i-1] + 1;
while B[i-1] != B[j] and j > 0 do
j = next[j] + 1;
end while;
next[i] = j;
end for;
End;
核心思想就是B与A在i处发生不匹配时,那么应该向右移动B。最笨的方法是每次都只移动一位,然后重头开始比较,那么时间复杂度为O(m*n)。KMP算法利用已经匹配部分字符串(B(1 to i-1))的特点,选择尽量大且不漏掉可能匹配的移动距离. 也就是B(1 to i -1)的前缀和后缀的最大相等值。
在hihocoder题库中一道非常标准的KMP题目(已解决),它求的是B在A中的出现次数。