AcWing KMP字符串 题解( KMP匹配字符串 模板)(KMP)

核心思想:当子串和母串不匹配时,直接让子串下移到下一次可以和前面部分字符串匹配的地方,节省了中间无效的匹配时间

#include<iostream>

using namespace std;

const int N = 1e5 + 10, M = 1e6 + 10;

int n, m;
char p[N], s[M];
int ne[N];

int main()
{
	cin>> n >> p + 1 >> m >> s + 1;//字符串的下标从1开始,所以从p+1开始读入 
	//计算前缀数组 
	for(int i = 2, j = 0; i <= n; i ++ ){//s[1]的前缀数组为0,所以直接从2开始匹配 
		while(j && p[i] != p [j + 1]) j = ne[j];//当p数组和子串不匹配时,子串直接移动到下一次可以和前面部分字符串匹配的位置 
		if(p[i] == p[j + 1]) j ++ ;//当子串数组的下一位和p数组的下一位匹配时,j++代表前缀后缀数组相同部分的长度++;
		ne[i] = j;//字符串第i位的kmp值为j; 
	}
	//字符匹配
	for(int i = 1, j = 0; i <= m; i ++ ){
		while(j && s[i] != p[j + 1])j = ne[j];//当s数组和p数组的下一位不匹配时,p数组直接移动到下一次可以和前面部分字符串匹配的位置
		if(s[i] == p[j + 1]) j ++ ;//当s数组和p数组匹配时,j++(j此时代表匹配的长度) 
		if(j == n){//当匹配的长度等于p字符串的长度时,代表全部匹配成功 
			cout<<i - n<<" ";//输出起始位置,即当前位置减去p字符串长度
			j = ne[j];//j移动到下一次可以和前面字符串匹配的位置 
		} 
	} 
	return 0; 
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值