题目:
仅对这个题而言,用普通的方法,就是所谓的BF,相信大家都能够实现,区别只是谁的代码更简练,但是实现的算法都是一样的,这里写写KMP,至于kmp前前后后的来龙去脉,这里不做讲解,自认为还没这个能力,在走访过的博客论坛技术贴中,也未曾清楚的明白作者所言为何物,这里没有贬低的意思,每个作者将自己明白和理解的东西能无私的分享出来,都是非常棒的!
这里给 大家提供几个讲解KMP的链接,是能够跟着走一遍就能明白的那种。
1. 阮一峰:字符串的KMP算法
2.相似的英文博客:jBoxer
看了这两篇文章,如果不用你自己生成next表,估计现在你可以很快的写出kmp算法,并能讲解清楚。下面看看维基百科里给出的匹配算法和生成next表的伪代码。维基:Knuth-Morris-Pratt algorithm
//kmp search pseudo code
伪代码:
algorithm kmp_search:
input:
an array of characters, S (the text to be searched)
an array of characters, W (the word sought)
output:
an integer (the zero-based position in S at which W is found)
define variables:
an integer, m ← 0 (the beginning of the current match in S)
an integer, i ← 0 (the position of the current character in W)
an array of integers, T (the table, computed elsewhere)
while m + i < length(S) do
if W[i] = S[m + i] then
if i = length(W) - 1 then
return m
let i ← i + 1
else
if T[i] > -1 then
let i ← T[i], m ← m + i - T[i]
else
let i ← 0, m ← m + 1
(if we reach here, we have searched all of S unsuccessfully)
return the length of S
//build next table
algorithm kmp_table:
input:
an array of characters, W (the word to be analyzed)
an array of integers, T (the table to be filled)
output:
nothing (but during operation, it populates the table)
define variables:
an integer, pos ← 2 (the current position we are computing in T)
an integer, cnd ← 0 (the zero-based index in W of the next
character of the current candidate substring)
(the first few values are fixed but different from what the algorithm
might suggest)
let T[0] ← -1, T[1] ← 0
while pos < length(W) do
(first case: the substring continues)
if W[pos - 1] = W[cnd] then
let cnd ← cnd + 1, T[pos] ← cnd, pos ← pos + 1
(second case: it doesn't, but we can fall back)
else if cnd > 0 then
let cnd ← T[cnd]
(third case: we have run out of candidates. Note cnd = 0)
else
let T[pos] ← 0, pos ← pos + 1
实现代码
按着伪代码我们试着实现一下。仅供参考。
void fill_table(string p, vector<int>& table)
{
table[0] = -1;
table[1] = 0;
int index = 2;
int cnt = 0;
while (index < p.size())
{
if(p[cnt] == p[index - 1])
p[index++] = ++cnt;
else if(cnt > 0)
cnt = table[cnt];
else
table[index++] = 0;
}
}
int Compare(string s, string p)
{
if(s.size() < p.size() || s.size() == 0 || p.size() == 0)
return s.size();
int m = 0;
int i = 0;
vector<int> table(p.size() + 1,0);
fill_table(p, table);
while (m + i < s.size())
{
if(i >= p.size()) return m;
if(s[m + i] == p[i]) ++i;
else{
m += i - table[i];
i = 0;
}
}
return s.size();
}