KMP与题目练习
最长相等前后缀是决定我们移位的关键
而且next数组的数值只与子串本身有关。
所以next[i]=j,含义是:下标为i 的字符前的字符串最长相等前后缀的长度为j。
练手写法
#include<iostream>
using namespace std;
int ne[1000010];
typedef struct{
char data[100010];
int length;
}Sstring; //串的数据结构
//Sstring 是串的数据结构
//typedef重命名结构体变量,可以用Sstring t 定义一个结构体。
Sstring s,t;
void Getnext(){
int j = 0,k = -1;
ne[0] = -1; //一定要设置初值!!
while(j < t.length-1){
if(k=-1||t.data[j]==t.data[k]){
ne[++j] = ++k; //最后一次进来的时候 j= t.length -2 出去就变为了 length-1了
}else k = ne[k]; //前缀的前缀
}
}
int KMPget(){
int i = 0,j = 0;
Getnext();
while(i < s.length&&j<t.length){
if(j==-1||s.data [i]==t.data [j]){ //相等就双指针 往前移 也有可能从头开始匹配
i++;j++;
}else j = ne[j];
}
if(j>=t.length) {
return i- t.length; //这里的i已经是length了所以可以直接减去t.length
}else return -1;
}
int main(){
int n,m;
cin>>m>>t.data>>n>>s.data;
s.length = n;
t.length = m;
int ans = KMPget();
cout<<ans<<endl;
return 0;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
主要要注意的地方是这个unsigned,比如在KMP的C++实现中如果用了string的话,就会有负数和size_t比较的情况,这个时候就会出现很奇怪的结果
同样的错误
如:
#include <bits/stdc++.h>
using namespace std;
int main(void)
{
vector<int> v;
v.push_back(1);
unsigned int a=-1;
cout<<a<<endl;
cout<<(-1>=v.size())<<endl;
return 0;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
解释原因
(vector.size()的一些常见错误总结)
推荐阅读