HDU-2087 剪花布条 (KMP)

题意:给出两个字符串,求其中一个在另一个中出现的次数(不可重复匹配)

思路:由于是不可重复的,所以相对于POJ-3461 (允许重复匹配),kmp的移动要进行修改,此时就将子串的下标置为0重新开始匹配即可

完整代码:

#include <iostream>
#include <cstdio>
using namespace std;
const int maxn = 1e4+10;
int num[100*maxn];
int num1[maxn];
int nex[maxn];
int N,M;
int k,len1,len2,ans=-1;
//求子字符串的nex数组 
void getnex(){
    int i=0,j=-1;
    nex[i]=j;
    while(i<len2){
        if(j==-1||num1[i]==num1[j]){
            i++;j++;
            nex[i]=j;
        }
        else j=nex[j];
    }
}
int KMP(){
    int i = 0, j = 0;
    getnex();
    while(i < N && j < M)
    {
        if(j == -1 || num[i] == num1[j])
        {
            i++; j++;
        }
        else
            j = nex[j];
    }
    if(j == M)
        return i -M + 1;
    else
        return -1;
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
    int T;
    cin>>T;
    while(T--){
        
        cin>>N>>M;
        for(int i=0;i<N;i++) cin>>num[i];
        for(int i=0;i<M;i++) cin>>num1[i];
        len1 = N ,len2 = M;
        ans = KMP();
        cout<<ans<<endl; 
    }
}

猜你喜欢

转载自www.cnblogs.com/Tianwell/p/11208627.html