zoukankan      html  css  js  c++  java
  • AcWing 831 KMP字符串

    给定一个模式串S,以及一个模板串P,所有字符串中只包含大小写英文字母以及阿拉伯数字。

    模板串P在模式串S中多次作为子串出现。

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

    输入格式

    第一行输入整数N,表示字符串P的长度。

    第二行输入字符串P。

    第三行输入整数M,表示字符串S的长度。

    第四行输入字符串M。

    输出格式

    共一行,输出所有出现位置的起始下标(下标从0开始计数),整数之间用空格隔开。

    数据范围

    1≤N≤104

    1≤M≤105

    输入样例

    3

    aba
    5

    ababa

    KMP算法求字符串匹配。文本串为S,匹配串为P,不难想到暴力做法,即从S和P的第一个字符开始,逐一比对,如果二者相同,那么S和P都前进到下一个字符,如果不相同,那么S回退到第一个字符之后的一个字符,作为新的比对起点,而P回退到第一个字符。

    KMP算法的思想在于,同样是逐一比对,但当遇到不相同字符时,S串的指针不回退,而P串的指针不必回退到第一个字符,而是j = next[j](假设j是模式串P的指针)。

    举例:

    文本串S:...REGRET...

    匹配串P:     REGROW

    这里EO不匹配,保持文本串S的指针i不变,将匹配串指针j移动到next[j]

    文本串S:...REGRET...

    匹配串P:    REGROW

    所以next[]数组的意义就是利用匹配串自身的信息--找到最长的相同的前缀和后缀,类似上面的示例,就可以将j移动到一个合适的位置,让P的后缀匹配到的S的内容用P的前缀来匹配。

    那么next[i]怎么求呢?假设我们已经知道next[j],递推next[j+1],如果next[j] = t,即在P[0, j)中,最大长度的真前缀和真后缀的匹配长度为t,如果P[j] = P[t],那很好,直接将这相同的二位分别加入真前缀和真后缀之中,那么整个P[0, j+1)的模式串的匹配长度就变为t+1。如果P[j]!=P[t],那么我们就继续缩小相同前后缀的范围,即看next[t],这代表了在P[0, next[t])长度内真前后缀的长度,再和P[j]比较,这一过程一直持续,知道找到了P[j]=P[t],或者t=-1时结束。

    代码

    //求next[]数组
    void get_next(int length){
        int t = Next[0] = -1;
        for(int j = 0; j < length-1; ){
            if(t < 0 || P[j] == P[t]){ t++; j++; Next[j] = t;}
            else 
                t = Next[t];
        }
    }
    
    //
    int main(){
        int n, m;
        scanf("%d", &n);
        scanf("%s", P);
        scanf("%d", &m); 
        scanf("%s", S);
        get_next(n);
        int i = 0, j = 0;
        while(j < m ){ //i指向匹配串,j指向文本串 
            if(i < 0 || S[j] == P[i]) { i++; j++;}
            else i = Next[i]; 
            if(i == n){ printf("%d ", j-i); i = Next[i-1]; --j;}
        }
    }
    
    
    
  • 相关阅读:
    CentOS6 图形界面'Basic server'条件下的(gnome)安装 .
    2013年 2月 春节期间 CgyWin 安装总结
    网络爬虫比较
    如何将nutch项目加载到MyEclipse中,生成一个web project
    读过的书
    NBearLite 用MsAccess数据库时 Count() 的错误(BUG?)
    测试Windows Live Writer
    VS2005 编辑器配色
    事务处理
    MVC MvcApplication 中在.CS文件(CodeBehide)中找不到服务器控件的解决办法
  • 原文地址:https://www.cnblogs.com/patrolli/p/11735811.html
Copyright © 2011-2022 走看看