电子学会七级-数据结构-KMP
KMP字符串匹配
https://www.luogu.com.cn/problem/P3375
#include<bits/stdc++.h>
using namespace std;
const int N = 1e6 + 50;
int nextval[N];
string s, a;
void get_next(){
int j = 0, k=-1;//匹配字符串下标 相同的最长前缀后缀个数
nextval[0] = -1;//j=0 k=-1
int slen = a.size();//匹配字符串长度
while (j < slen){//没到字符串结尾 继续匹配
//k==-1 初始或者没有匹配回退到-1
//a[j]==a[k]
if (k == -1 || a[j] == a[k]){//第一个开始匹配 或者在匹配成功的基础上 都+1
j++; k++;
nextval[j] = k;
}
else k = nextval[k];//找前一个成功k 在while循环判断是否可以匹配成功 或者到第一个了
}
}
void kmp(){
int i = 0, j=0;//i待匹配字符串下标 j匹配字符串下标
int slen = s.size(), plen = a.size();//slen匹配字符串长度 plen匹配字符串长度
while (i < slen && j < plen){//不到结尾 进行匹配
//如果j=-1说明已经匹配的没有相同的可以使用 i继续下一个j从头开始匹配
//如果字符相同i j都进行下一个匹配
if(j == -1 || s[i] == a[j]){
i++;
j++;
if (j == plen){//如果匹配到了继续右移
//输出匹配字符串起点位置
cout << i - j + 1 <<endl;
//j最长公共前后缀的长度 即前面有几个相同的
//下一个匹配字符对应匹配字符串的起点
j = nextval[j];
}
}
else j = nextval[j];//不匹配找上一个最长公共前后缀的起点开发匹配
}
}
int main(){
// ios::sync_with_stdio(false);
cin >> s >> a;
int len = a.size();
get_next();//计算匹配字符串每个位置的最长公共前后缀的长度
kmp();//kmp方法匹配并输出所有匹配的起点
for (int i = 1; i <= a.size(); i ++)//输出匹配字符串a的所有位置最长公共前后缀的长度
cout << nextval[i] << ' ';
cout << endl;
return 0;
}
剪花布条
http://acm.hdu.edu.cn/showproblem.php?pid=2087
算法竞赛入门到进阶 P200
作者:newcode 更多资源请关注纽扣编程微信公众号
从事机器人比赛、机器人等级考试、少儿scratch编程、信息学奥赛等研究学习