ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

[ACW]831.KMP字符串

2019-10-06 12:54:39  阅读:425  来源: 互联网

标签:831 匹配 cn int i2 ne i1 ACW KMP


题目描述:求出模板串P在模式串S中所有出现的位置的起始下标。

题目链接

tips:

  1.next数组多求一位,求出整个P串的最大前后缀匹配长度。

  2.当匹配成功时,p串向后推多少?此时s串的指针i1已经指向完全匹配的下一位了,只需要i2跳跃到整个串最大前后缀匹配长度指示的位置开始比较就行;用反证法假设证推矛盾。

  3.位置下标从0开始,长度与下标的对应。

  4.next数组有递推的感觉,刚开始的处理,比如i-1和cn=0的处理,就很巧妙。

//1.首A代码,尽管写的比较丑,还是留影纪念下吧
//2.卡了好久的一个点是,自己觉得逻辑没有错误,输出就是不对,是什么原因呢??
//输出语句的位置没放在while循环里
//3.自己独立完成推了第一次匹配成功后,该怎么接着继续匹配?
//我的解法是求next数组时,多求一位,求出整个P串的最长前缀和最长后缀的匹配长度
//匹配成功时,i1已经指向完全匹配位置的下一位,
//4.用反证法进行证明:i2指针的跳跃和被否定掉的位置不可能匹配成功,即不可能出现更长的前缀和后缀相匹配
//5.一路都相等;没配上之前,两个字符串都一样
//6.注意比较完之后下标指针i1、i2的更新
#include<iostream>
#include<cstdio>
#include<string.h>
using namespace std;
const int N=10010;
const int M=100010;
char p[N],s[M];
int ne[N];
int n,m;
void getne(char* p){
    int pLen=strlen(p);
    ne[0]=-1;
    ne[1]=0;
    int i=2;
    int cn=0;
    while(i<=pLen){
        if(p[i-1] == p[cn]){
            ne[i++]=++cn;
        }else if(cn > 0){
            cn=ne[cn];
        }else{
            ne[i++]=0;
        }
    }
    /*
    for(int i=0;i<=pLen;i++){
        printf("%d ",ne[i]);
    }
    */
    return ;
}
int main(){
    cin>>n>>p>>m>>s;
    getne(p);
    int pLen=strlen(p);
    int sLen=strlen(s);
    int i1=0;//甲指针
    int i2=0;//乙指针
    for(;i1<m;i1++){
        while(i1<sLen && i2<pLen){
            if(s[i1] == p[i2]){
                i1++;
                i2++;
            }
            else if(ne[i2]== -1)// 思考ne[i2]什么时候等于-1?当ne[i2]==-1时,i2已经指向了p串开头0
            {
                i1++;
            }
            else{
                i2=ne[i2];
            }
            if(i2 == pLen){
                printf("%d ",i1-pLen);
                i2=ne[i2];
        }
        }

    }

    return 0;
}
View Code

ps:kmp算是才刚刚解锁,学习花了大概一周的时间

ref:左神,以及网上的博客,致谢!

 

标签:831,匹配,cn,int,i2,ne,i1,ACW,KMP
来源: https://www.cnblogs.com/SUMaywlx/p/11627026.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有