KMP字符串-acwing

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 ;
}

  

posted @ 2020-07-18 22:37  Lazy_tiger  阅读(180)  评论(0编辑  收藏  举报