POJ - 3461 Oulipo解题报告(KMP)

题目大意:

多组测试数据,每组测试数据两个字符串,让你找出一个字符串里有多少另一个字符串。

分析:

应该就是kmp的魔板题,但是可能是因为我kmp掌握的不好吧,卡了好久好久。
这里一个比较巧妙地思维转换就是,在找到一个模板串之后,ans++,如何寻找下一个,这个事情就可以很巧妙地看成是模板串的最后一个字母之后还有一个假想的与之前任何一个字符串都不同的字符,这个字符当然也不可能和原字符串的任何一个匹配成功了,也就是说如果在这个假想的最后一个字符串的位置匹配失败,那么就计数+1,然后继续按照匹配失败的情况接着继续进行。

代码:

#include<iostream>
#include<stdio.h>
#include<string.h>
#define maxm 10500
#define maxn 1000500

using namespace std;

int next[maxm]={0};
char model[maxm]={0};
char a[maxn];
int test;

void my_next()
{
    int j=-1;int k=0;
    next[0]=-1;
    int n=strlen(model);
    while(k<n)
    {
        if(j!=-1&&model[j]!=model[k])
        {
            j=next[j];continue;
        }
        j++;k++;
        if(model[j]==model[k])next[k]=next[j];
        else next[k]=j;
        //cout<<"next["<<k<<"]="<<next[k]<<" ";
    }
    return;
}

void ceshi1()
{
    for(int i=0;i<strlen(model);i++)
    {
        cout<<next[i]<<" ";
    }
    cout<<endl;
}
/*
int my_kmp()
{
    int j=0;
    int s=0;
    int n=strlen(a);int m=strlen(model);
    for(int i=0;i<n;i++)
    {
        if(j==m)
        {
            i=i-m+1;
            j=0;
            s++;
        }
        if(model[j]==a[i])j++;
        else
        {
            if(next[j]==-1)j=0;
            else 
            {
                j=next[j];i--;
            }
        }
    }
    return s;
}
*/
/*int my_kmp()
{
    int s=0;
    int i=0,j=0;//i指向model,j指向a;
    int n=strlen(a),m=strlen(model);
    for(j=0;j<n;)
    {
        //cout<<j;

        if(a[j]==model[i])
        {
            i++;j++;
            if(i>=m)
            {
                s++;
                if(j>=n)return s;
                i=0;j=j-m+1;
            }
            continue;
        }
        //cout<<"po";
        j=j-next[i];
        i=0;
    }
    return s;
}
*/
int my_kmp()
{
    int ans = 0;
    int plen = strlen(model);
    int tlen = strlen(a);
    int i = 0, j = 0;
    while (i < tlen)
    {
        if (j == -1 || model[j] == a[i])
        {
            i++;
            j++;
        }
        else
        {
            j = next[j];
        }
        if (j == plen)
        {
            ans++;
            //cout<<next[j]<<" "<<j<<" "; 
            j = next[j];
        }
    }
    return ans;
}
int main()
{
    cin>>test;
    while(test--)
    {
        scanf("%s",model);
        scanf("%s",a);
        my_next();
        cout<<my_kmp()<<endl;

        //ceshi1();
        //next2(model);
        //ceshi1();
        /*memset(a,0,sizeof(a)); memset(model,0,sizeof(model));*/
    }
}
全部评论

相关推荐

大方的大熊猫准备进厂:1.教育背景:你希望从事什么专业的工作你的主修课就是什么;成绩优秀是你应该做的,没什么可描述的,成绩不优秀也许人家在大学忙着创业呢?(成绩优秀不一定是好事,只能说明多元化的大学你上成了高中,没有真正上明白大学,反而体现了你死板,不爱社交,没有别的突出能力) 2.实践经历:你想表达的意思没有说清楚。你是说你会个性化服务,还是你有实习经历。如果没有带来,经济收益,表彰,更好的发展前景,那你还不如说说提升了自己哪些技能。你说有人给你送锦旗我都能明白你优秀,但是你说你会xxxx,你说这话谁信,证据呢。 3.入伍经历:你描述的就是你的工作职责或者你应该做的,并没有体现出来你把这个事情做好了,而且入伍经历并不能证明你能干好你要应聘的工作,不如只写经历其余所有内容都不写。 4.荣誉技能:重点突出一下,但不要过多描述,这些荣誉的含金量懂得都懂。 重点:你要应聘什么工作(具体岗位,实习生不具体),你的期望薪资
点赞 评论 收藏
分享
企业都这么缺人了吗?缺人为什么还给白菜价!
真起不了响亮的名字:我给你出个主意,把公司报出来,让牛友去投,岂不美哉
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务