#include
<
iostream
>
#include
<
string
>
#include
<
vector
>
#include
<
algorithm
>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
using
namespace
std;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
void
get_next(
const
string
&
T,vector
<
int
>&
next )
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
unsigned int i=0;
next[0] = -1;
int k = -1;
unsigned int j = 0;
while( j<T.size() -1 ) //每次总是计算下一值.
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
if( k == -1 || T[j] == T[k])
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
++j;++k;
next[j]=k;
}
else
k=next[k];
}
copy(next.begin(),next.end(),ostream_iterator<int>(cout," "));
}
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
void
get_nextval(
const
string
&
T,vector
<
int
>&
next )
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
unsigned int i=0;
next[0] = -1;
int k = -1;
unsigned int j = 0;
while( j<T.size() -1 ) //每次总是计算下一值.
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
if( k == -1 || T[j] == T[k])
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
++j;++k;
if(T[j] != T[k]) //if like this :aaaaaaab;
next[j] = k;
else
next[j] = next[k];
}
else
k=next[k];
}
copy(next.begin(),next.end(),ostream_iterator<int>(cout," "));
}
string
T(
"
abaabcac
"
);
vector
<
int
>
next(T.size());
int
Index_KMP(
string
s,
string
T,
int
pos)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
int i=pos;
int j=0;
while( i<s.size() && j<T.size())
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
if( (j==0 ||j==-1) || s[i]==T[j])
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{++i;++j;}
else
j=next[j];
}
if(j==T.size())
return i-j;
else
return 0;
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
}
int
main()
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
copy(T.begin(),T.end(),ostream_iterator<char>(cout," "));
cout<<endl;
get_next(T,next);
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
//string s("ababcabcacbab");
string s("aaabaabaabcac");
cout<<endl;
cout<< Index_KMP(s,T,0);
system("pause");
return 0;
}
KMP 是很经典,网上随便google一下就很多,我就不再对算法累述了.我所参考的是严未敏的<<数据结构>>第79页.
KMP算法能在o(m+n)时间内完成串的匹配操作.(n 主窜长度,m子穿长度)想象一下,比如你编写了一个文本软件,再在上面实现查找功能.这时用kmp算法优势就体现出来了.
KMP包括两部分,匹配和求next值.匹配算法比较具体易懂,但求next函数代码技巧要求很高,如此简洁高效的实现不是凡人所为! get_nextval是对get_next的改进,特别是当子窜是"aaaaab"之类(子窜中有多个连续相同字符)有更高的匹配效率.