当前位置 博文首页 > 文章内容

    #10043.「一本通 2.2 例 1」剪花布条 - KMP变形 - 求不重叠子串在原串中出现的次数

    作者: 栏目:未分类 时间:2020-11-04 15:01:25

    本站于2023年9月4日。收到“大连君*****咨询有限公司”通知
    说我们IIS7站长博客,有一篇博文用了他们的图片。
    要求我们给他们一张图片6000元。要不然法院告我们

    为避免不必要的麻烦,IIS7站长博客,全站内容图片下架、并积极应诉
    博文内容全部不再显示,请需要相关资讯的站长朋友到必应搜索。谢谢!

    另祝:版权碰瓷诈骗团伙,早日弃暗投明。

    相关新闻:借版权之名、行诈骗之实,周某因犯诈骗罪被判处有期徒刑十一年六个月

    叹!百花齐放的时代,渐行渐远!



    题意

    中文题。题目链接:https://loj.ac/problem/10043

    这题代码和 HDU2087 的一样,但是注意,该AC代码在这两个题目的样例都能过,但是这两题的输入不一样!!!

    不要直接交!!!改输入就行!!!

    思路

    该题是KMP的模板略微变形的题目。

    KMP的模板是求子串在原串中出现了几次,

    本题是可以间接看作是子串不重叠的在原串中出现了几次。

    所以我们只需要加两行代码,即在 kmp() 函数中加入:

    if(j==lens)
          j=0,cnt++;            //(j=0 因为题目规定的是不能重叠,也就相当于已经找到的位置不允许再次使用!)
    

    AC代码

    #include<stdio.h>
    #include<iostream>
    #include<string.h>
    using namespace std;
    
    const int N=1010;
    int lens,lent,nex[N];
    char s[N],t[N];
    
    void getnex()
    {
        int i=0,j=-1;
        nex[0]=-1;
        while(i<lens)
        {
            if(j==-1||s[i]==s[j])
                nex[++i]=++j;
            else
                j=nex[j];
        }
    }
    
    int kmp()
    {
        int i=0,j=0,cnt=0;
        while(i<lent)
        {
            if(j==-1||t[i]==s[j]) // if j<0
                i++,j++;
            else
                j=nex[j];
            if(j==lens)
                j=0,cnt++;
        }
        return cnt;
    }
    
    int main()
    {
        while(cin>>t)
        {
            lent=strlen(t);
            if(lent==1&&t[0]=='#')
                break;
            cin>>s;
            lens=strlen(s);
            getnex();
            cout<<kmp()<<endl;
        }
        return 0;
    }