https://www.acwing.com/problem/content/833/
暴力谁都会,完全就是一句话:next[i] = j ; //以i为结尾的非前缀子串与(从1开始的前缀的字符串)相等的长度是多少,然后就是j咯 、、之前记忆力不好又不经常使用的我总是忘记
#include <iostream> #include <cstring> #include <cmath> #include <stdio.h> #include <cstdlib> #include <algorithm> #include <vector> #include <set> #include <map> #include <iomanip> #define rep(i,a,b) for(int i = a; i <= b ; i ++ ) #define pre(i,a,b) for(int i = b ; i >= a ; i --) #define ll long long #define inf 0x3f3f3f3f #define ull unsigned long long #define ios ios::sync_with_stdio(false),cin.tie(0) using namespace std; typedef pair<int,int> PII ; /* ull gethash(int i,int j){//get hash of [i,j] return hs[j]-hs[i-1]*base[j-i+1]; } bool judgehash(int i,int j){ ull x=gethash(i,j);//the part of son‘s hash int id=lower_bound(v.begin(),v.end(),x)-v.begin();//found of two found if(id==v.size())return false;//if not found else return v[id]==x; //judge whether be found } */ /* void preget(int t) { if(t == 0){ return; } else if(t==1){ fish++; } else if(t==2){ h+=1; } else if(t==3) { fish++,h++; } else return ; } int done() { yuer+=h; h=0; int cnt=0; if(fish==0 && yuer==0) { return 0; } else if(fish==0){ cnt=1; yuer--; } else { if(fish==1){ cnt=fish; fish--; } else{ if(yuer<fish-1){ cnt=yuer; yuer=0; fish-=yuer; } else if(yuer==fish-1){ cnt=fish; yuer=0,fish=0; } else if(yuer==fish){ cnt=fish+1; fish=0,yuer=0; } else if(yuer>fish){ cnt=fish+2; yuer-=(fish+1); } } } return cnt; } */ const int N = 2e5 + 10,M=2e6 + 10; int n ,m; char p[M],s[M]; int ne[N]; int main() { ios; cin>>n>>(p+1)>>m>>(s+1); //get next position 以i为结尾的非前缀字符串与从1开始的字符串的最大长度 for(int i = 2,j=0;i<=n;i++){ while(j && p[i] != p[j+1]){ j=ne[j]; } if(p[i]==p[j+1]){ j++; } ne[i]=j; } for(int i=1,j=0;i<=m;i++) //匹配过程 { while(j && s[i] != p[j+1]){//j没有退回起点或者是s[i]和s[j]不匹配了 j=ne[j]; } if(s[i]==p[j+1]){ j++; } if(j==n){//匹配成功 cout<<i-n<<" "; //因为这道题下标是从0开始的,所以+1去掉即可 j=ne[j]; //以j为终点的坐标与1开始的最大长度赋给j } } return 0 ; }