这里写目录标题
参考罗老师的讲解,讲得很细致,易懂
https://blog.csdn.net/weixin_43914593/article/details/117533364?spm=1001.2014.3001.5502
求next数组
#include<bits/stdc++.h>
using namespace std;
//通过计算返回子串t的next数组
//next数组:第j位字符前面j-1位字符组成的子串的前后缀重合字符数
//定义:当主串与模式串的某一位字符不匹配时,模式串要回退的位置
int Next[100];
/*void getNext(string p){
int k=-1,j=0;//初始化 //k值表示当前最长匹配成功字符串的长度
Next[0]=-1;
while(j < p.length() - 1){
if(k == -1 || p[k] == p[j]){//匹配下一个,//当前字符与匹配成功的下一字符相等则再次匹配成功
k++;j++;
Next[j]=k;
}
else k = Next[k];//回溯找最大相同前缀的最大相同前缀.....d的长度
}
for(int i=0;i<p.length();i++)
cout<<Next[i]<<" ";
}
*/
void getNext(string a)
{
int len=a.length();
Next[1]=0;Next[0]=0;
for(int i=1;i<len;i++)
{
int j=Next[i];
while(a[i]!=a[j]&&j)
{
j=Next[j];
}
if(a[i]==a[j]) Next[i+1]=j+1;
else Next[i+1]=0;
}
}
int main()
{
string sa;cin>>sa;
get_next(sa);
return 0;
}
/*
abcabcacab
a b c a b c a c a b
j 0 1 2 3 4 5 6 7 8 9
Next -1 0 0 0 1 2 3 4 0 1
*/
经典字符串匹配题目
了解https://www.acwing.com/problem/content/833/
AC代码:
#include<iostream>
using namespace std;
int n,m;
string p,s;
const int N=100005;
int Next[N];
//求p的Next数组
void getNext()
{
Next[0]=Next[1]=0;
for(int i=1;i<n;i++)
{
int j=Next[i];
while(p[i]!=p[j]&&j) //一直回退到匹配上
{
j=Next[j];
}
if(p[i]==p[j]) Next[i+1]=j+1; //注意不是Next[i]+1,j已经往前回溯了
else Next[i+1]=0;
}
}
int main()
{
cin>>n>>p;
cin>>m>>s;
getNext();
/* for(int i=0;i<=n;i++)
{
cout<<Next[i]<<" ";
}
cout<<endl;*/
//进行匹配,可以找到所有匹配的位置信息
int j=0;
for(int i=0;i<m;i++)
{
while(s[i]!=p[j]&&j)
{
j=Next[j]; //注意这块儿是往前不断回溯,直到匹配上,不是只判断一次
}
if(s[i]==p[j]) j++;
if(j==n) //模式串全部匹配上了
{
cout<<i-j+1<<" "; //匹配上的起始位置
}
}
return 0;
}
Censoring S
题目链接:https://www.luogu.com.cn/problem/P4824
AC代码:
#include<bits/stdc++.h>
#define N 1000010
using namespace std;
int la,lb,res;
char a[N],b[N];
int p[N],f[N];//分别表示B串自身匹配的结果、A串与B串匹配的结果
int St[N],top;
int main()
{
int i,j;
scanf("%s",a+1);
scanf("%s",b+1);
la=strlen(a+1);
lb=strlen(b+1);
for(i=2,j=0;i<=lb;i++) {//自身匹配
while(j&&b[i]!=b[j+1])
j=p[j];
if(b[i]==b[j+1])
j++;
p[i]=j;
}
for(i=1,j=0;i<=la;i++) {//A与B匹配
while(j&&a[i]!=b[j+1])
j=p[j];
if(a[i]==b[j+1])
j++;
f[i]=j;//记录结果
St[++top]=i;//入栈
if(j==lb)//如果匹配成功,弹出,并更新j值
top-=lb,j=f[St[top]];
}
for(i=1;i<=top;i++)//大功率输出
printf("%c",a[St[i]]);
return 0;
}