KMP算法要解决的问题:在 字符串 (也叫主串)中 的模式(pattern)定位 。
通俗一点就相当于 在 Π 中找一串自己想找的号……(一定有,但比较难找,哈哈哈)
主串:S 模式串:T;如果在 T 在 S 中出现,返回具体位置,否则返回 0 。
大家思考一下这个问题:
现给 S:abcababab… ;T : abcabx
在S中找T,我们大脑可以快速给我们答案,S中目前显示的并没有T。
我们不妨思考一下我们的大脑是如何处理的:
我当时认为我的脑子是这样运行的,因为a != x,所以模式串T直接从不相等的地方再开始比较,然后发现自己错了。如果把模式串T的末尾 x 改为 d:
大家看一下,是不是懂了。我们的大脑因为T[1] == S[4],所以再从S[4]开始比较,最后在主串S中找到了模式串T。
上面是 浅分析下的大脑的处理方式,现在我们再想加快一下速度,那么再向深处想,此时便引入相似度的概念。
(引入变量 j : j 值的大小取决于当前字符之前的串的前后缀的相似度。)
刚才是T[7] != S[7] ;我们判断T的相似度
void get_next(String T,int* next)//String 是自定义的类型
{
int i = 1;
int j = 0;//当前字符之前的串的前后缀相似度相似度
next[1] = 0;//next 是存放j值的数组
while(i < T[0])//T[0] 表示串的长度
{
if(j == 0 || T[i] == T[j])
{
++i;
++j;
next[i] = j;
}
else
j = next[j];
}
}
因此直接T[4] 与 S[7] 比较,省略T[1] T[2] T[3] 的比较过程。
//返回子串T在主串S中的位置。若不存在,返回O;
int Index_KMP(String S, String T)
{
int i = 1;
int j = 1;
int next[255];
get_next(T,next);
while(i <= S[0] && j <= T[0])
{
if(j == 0 || S[i] == T[i])
{
++i;
++j;
}
else
{
j = next[j];
}
}
if(j > T[0])
return i - T[0];
else
retrun 0;
}
结束。。。