[caioj]KMP总结(?)

来源:互联网 发布:决战武林宠物升级数据 编辑:程序博客网 时间:2024/06/05 17:25

KMP…处理前缀吧?

caioj1177: [视频]KMP模版:子串是否出现(元问题 by scy)

【题意】
有两个字符串SA和SB,SA是母串,SB是子串,问子串SB是否在母串SA中出现过。
如果出现过输出第一次出现的起始位置和结束位置,否则输出”NO”

(模板题不懂可以看视屏~良心视屏哦!)
灯教授的良心博客:http://www.cnblogs.com/Never-mind/p/7598880.html

#include<cstdio>#include<cstring>using namespace std;char sa[1110000],sb[1100];//sa是母串,sb是子串 int p[1100];// p[i]表示sb中 以第i个字符为结尾结尾结尾,往前最多拉多少个字符(sb[i]结尾的后缀)  可以 完全 匹配 sb的前缀 即 p[i]~i可以匹配1~i-p[i]int main(){    //freopen("a.in","r",stdin);freopen("a.out","w",stdout);     int lena,lenb,i,j;    scanf("%s",sa+1);lena=strlen(sa+1);    scanf("%s",sb+1);lenb=strlen(sb+1);    p[1]=0;    for(i=2;i<=lenb;i++)    {        j=p[i-1];         while( j>0 && sb[i]!=sb[j+1]) j=p[j];        if(sb[i]==sb[j+1]) p[i]=j+1;else p[i]=0;     }    int st,ed;    j=0;    for(i=1;i<=lena;i++)    {        while( j>0 && sa[i]!=sb[j+1]) j=p[j];        if(sa[i]==sb[j+1]) j++;        if(j==lenb){   ed=i;st=i-lenb+1;  break;}    }    if(j==lenb) printf("%d %d\n",st,ed); else printf("NO\n");     return 0;}

caioj1457: 【KMP】重复的子串

【题意】
我们定义两个字符串a和b的乘法: a*b ,就是把它们连接起来。比如: a = “abc” ,b = “def” ,那么 a*b = “abcdef”.
由此推广,字符串的幂运算: a^0 = “” (空字符串)
a^(n+1) = a*(a^n).
给一个字符串s,假设存在 a^n=s,求n的最大值。

后缀的长度能不能被len整除即可得
求p就行了ovo

#include <cstdio>#include <cstring>using namespace std;char a[1100000];int p[1100000];int main(){    while (scanf("%s",a+1)!=EOF)    {        if (a[1]=='.') break;        int len=strlen(a+1);        p[1]=0;        int j=0;        for (int i=2;i<=len;i++)        {            j=p[i-1];            if (j>0&&a[i]!=a[j+1]) j=p[j];            if (a[i]==a[j+1]) p[i]=j+1; else p[i]=0;        }           if (len%(len-p[len])==0) printf("%d\n",len/(len-p[len])); else printf("1\n");    }     return 0;}

caioj1458: 【KMP】判断循环段位置

【题意】
给一个字符串,如果在前 i 位置处满足连续循环A^K(A:单位循环段,K:循环个数),
则输出i和K(仅输出K>1的情况,按i的递增顺序)

和第一题差不多?

#include <cstdio>#include <cstring>using namespace std;char a[1100000];int p[1100000];int main(){    scanf("%s",a+1);    int len=strlen(a+1);    p[1]=0;    int j=0;    for (int i=2;i<=len;i++)    {        j=p[i-1];        if (j>0&&a[i]!=a[j+1]) j=p[j];        if (a[i]==a[j+1]) p[i]=j+1; else p[i]=0;    }       for (int i=2;i<=len;i++)    {        if (i%(i-p[i])==0&&i/(i-p[i])>1) printf("%d %d\n",i,i/(i-p[i]));    }    return 0;}

caioj1459: 【KMP】所有前缀等于后缀的情况

【题意】
给出一个字符串S. 1 <= S的长度 <= 400000.
找出所有S的前缀等于后缀的情况。按长度递增输出长度。相互之间用空格隔开。

还是和第一题差不多?

#include <cstdio>#include <cstring>using namespace std;char a[410000];int p[410000],ans[410000],m;int main(){    while (scanf("%s",a+1)!=EOF)    {        int len=strlen(a+1);        p[1]=0;        int j=0;        for (int i=2;i<=len;i++)        {            j=p[i-1];            while (j>0&&a[i]!=a[j+1]) j=p[j];            if (a[i]==a[j+1]) p[i]=j+1; else p[i]=0;        }        int i=len;        m=0;        while (i!=0)        {            m++;            ans[m]=p[i];            i=p[i];        }        for (int i=m-1;i>0;i--) printf("%d ",ans[i]);        printf("%d\n",len);    }    return 0;}

caioj1460: 【KMP】字符串匹配

【题目描述】
给出两个字符串sa和sb,求出sa能在sb中匹配的最大次数。

和模版差不多….

#include <cstdio>#include <cstring>using namespace std;char a[1100000],b[1100000];int p[1100000];int main(){    int u,ans;    scanf("%d",&u);    while (u--)    {        ans=0;        scanf("%s",b+1);        int lenb=strlen(b+1);        scanf("%s",a+1);        int lena=strlen(a+1);        p[1]=0;        int j=0;        for (int i=2;i<=lenb;i++)        {            while (j>0&&b[i]!=b[j+1]) j=p[j];            if (b[i]==b[j+1]) p[i]=j+1; else p[i]=j;            j++;        }        j=0;        for (int i=1;i<=lena;i++)        {            while (j>0&&a[i]!=b[j+1]) j=p[j];            if (a[i]==b[j+1]) j++;            if (j==lenb) ans++;        }        printf("%d\n",ans);    }    return 0;}

其实不得不说,重复学习这件事情真的很重要

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 传送门骑士联机读条慢怎么办 被打成轻伤派出所不抓人怎么办 有人上门找事怎么办算正当防卫吗 win10 电脑账户被停用怎么办 电脑一键还原后黑屏怎么办 win一键还原后黑屏怎么办 打架对方群殴我我怎么办 杀了人没钱赔怎么办 团伙打架被对方所刀捅伤怎么办 过失致人重伤赔偿不起怎么办 被别人打了派出所不管怎么办 先动手的被打伤怎么办 自为伤了人怎么办? 孩子被打不敢还手怎么办 小孩给电打了怎么办 电打了手都黑了怎么办 手指被电打伤了怎么办 电打了手有点麻怎么办 没打人对方确弄个轻伤证明怎么办 对人造成轻伤害怎么办 如果有人要砍我怎么办 美版手机坏了怎么办 战地4ping太高怎么办 喝了红牛睡不着怎么办 球球大作战总是闪退怎么办解决方法 球球大作战手机号己绑定怎么办 弄的底窝中药味太大怎么办 锤子手机上不了网怎么办 ppt没保存就卡了怎么办 ppt卡了没保存怎么办 匡威鞋舌头跑偏怎么办 霍尼韦尔dcs cb锁死怎么办 谷歌身份验证器丢失 怎么办 叛乱2手雷没了怎么办 王者转移号封了怎么办? 电脑被入侵挖矿怎么办 我把exe删除了怎么办 大学图书馆借书超过期限了怎么办 win10更新完鼠标没有了怎么办 打开软件提示运行出错怎么办 电脑中了u盘病毒怎么办