电子学会七级-数据结构-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

posted @ 2022-04-25 21:26  new-code  阅读(33)  评论(0编辑  收藏  举报