第十三次总结

  题目连接:

这个题就是并查集的模板题

一开始我想按照我在《大话数据结构》上的来写,但是上面就是一个建立next数组,没有之后的判断,而且上面的next数组不是以下标0开始的,而是以下标1开始的,像这样,

int getnext(char ch[],int length,int next){
next[1]=0;
int i=1,j=0;
while(i<length){
	if(j==0||ch[i]==ch[j]){
			i++;
			j++;
			if(ch[i]!=ch[j])
			next[i]=j;
			else
			next[i]=next[j];
		}
	}
	else
	j=next[j];
}

而且我想用string类型来写这个题(就是单纯的懒),这样的话我干脆就不用这个递推的方式来写了,用循环来找next数组也不是不可以

思路:我们先要创建好next数组,也就是在marknext函数中去建立,然后去KMP函数中寻找

思路是不难,关键就是在与理解如何创建next数组和KMP寻找中

我们在创建next数组的时候,如果j为0时候,要让j等于next[j-1]也就是0(这一步我们单独写也可以),又或者是当brr[j]!=brr[i]的时候,就要让j等于你匹配失败前的next数组的值,让子串(也就是模式串)进行回溯,如果没有进行while循环的话,也就代表着我们此时主串和子串的相同最大先后缀+1,因为是相同的,就让j++让next[i]对应的值增加

然后是KMP函数里面的判断,为了方便我还是用的for循环的,当j不等于0并且brr[j]!=arr[i]的时候,我们就要进行j的回溯,回溯多少就看next[j-1]的值是多少,如果它们相等,就让j++,进行下一个字符的判断,也就是让主串和子串都向后移动一个位置,最后,要是在主串中找到了子串,我们就打印出是第几个就好了,但是要注意,因为第几个是以1开始的,而我们的数组是从0开始的,所以说需要i+1,而且长度的计算也就从1开始的,也要+1,

#include<bits/stdc++.h>
using namespace std;
#define maxn 1000005
string arr,brr;
int len1,len2;
int nextttt[maxn];
void marknext(){
	nextttt[0]=0;
	int j=0;
	for(int i=1;i<len2;i++){
		while(j&&brr[j]!=brr[i])
		j=nextttt[j-1];
		if(brr[j]==brr[i])
		j++;
		nextttt[i]=j;	
	}
}
void KMP(){
	int j=0;
	for(int i=0;i<len1;i++){
		while(j&&brr[j]!=arr[i])
		j=nextttt[j-1];
		if(brr[j]==arr[i])
		j++;
		if(j==len2)
		printf("%d\n",i+1-len2+1); 
	}
}
int main(){
	cin>>arr;
	cin>>brr;
	len1=arr.length();
	len2=brr.length();
	marknext();
	KMP();
	for(int i=0;i<len2;i++)
	cout<<nextttt[i]<<" ";
} 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值