Luogu 3375 【模板】KMP字符串匹配(KMP算法)


Luogu 3375 【模板】KMP字符串匹配(KMP算法)

Description

如題,給出兩個字符串s1和s2,其中s2為s1的子串,求出s2在s1中所有出現的位置。

為了減少騙分的情況,接下來還要輸出子串的前綴數組next。如果你不知道這是什么意思也不要問,去百度搜[kmp算法]學習一下就知道了。

Input

第一行為一個字符串,即為s1(僅包含大寫字母)

第二行為一個字符串,即為s2(僅包含大寫字母)

Output

若干行,每行包含一個整數,表示s2在s1中出現的位置

接下來1行,包括length(s2)個整數,表示前綴數組next[i]的值。

Sample Input

ABABABC
ABA

Sample Output

1
3
0 0 1

Http

Luogu:https://www.luogu.org/problem/show?pid=3375

Source

字符串匹配,KMP

解決思路

關於KMP算法,請參考我的這篇文章
那么要注意的是,我的這種方法求出來的Next數組(本文中用F表示)要+1才是最后要輸出的結果,具體請看鏈接。

代碼

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<string>
using namespace std;

const int maxN=1000001;
const int maxM=2001;
const int inf=2147493647;

int n,m;
string A,B;
int F[maxN];

int main()
{
    cin>>A>>B;
    n=A.size();;
    m=B.size();
    //Solve_Next
    
    F[0]=-1;
    
    for (int i=1;i<m;i++)
    {
        int j=F[i-1];
        while ((B[j+1]!=B[i])&&(j>=0))
            j=F[j];
        if (B[j+1]==B[i])
            F[i]=j+1;
        else
            F[i]=-1;
    }
    
    //for (int i=0;i<m;i++)
    //    cout<<F[i]<<' ';
    //cout<<endl;
    
    int i=0,j=0;
    
    while (i<n)
    {
        if (A[i]==B[j])
        {
            i++;
            j++;
            if (j==m)
            {
                printf("%d\n",i-m+1);
                j=F[j-1]+1;
            }
        }
        else
        {
            if (j==0)
                i++;
            else
                j=F[j-1]+1;
        }
    }
    
    for (int i=0;i<m;i++)
        cout<<F[i]+1<<' ';//注意這里要+1
    cout<<endl;
    return 0;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM