zoukankan      html  css  js  c++  java
  • KMP算法

     
    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=1010;
    #define inf 0x3fffffff
    int Next[maxn];
    string s1,s2;
    int m,n;
    void buildNext(){
        Next[0]=-1;
        int i;
        for(int j=1;j<m;j++){
            i=Next[j-1];//存储最大前缀的最后一个值的下标
            while((i>=0)&&(s2[i+1]!=s2[j])){//若当前前缀不符合,则回退,找寻次大的前缀
                i=Next[i];
            }
            if(s2[i+1]==s2[j]){
                Next[j]=i+1;
            }
            else{//i<0,不存在前缀
                Next[j]=-1;
            }
        }
    }
    
    int main(){
        cin>>s1>>s2;
        n=s1.length();
        m=s2.length();
        buildNext();
        int i=0,j=0;
        while(i<n&&j<m){
            if(s1[i]==s2[j]){
                i++;
                j++;
            }
            else if(j>0){
                j=Next[j-1]+1;
            }
            else{
                i++;
            }
        }
        if(j==m){
            cout<<i-m<<endl;
        }
        else{
            cout<<-1<<endl;
        }
        return 0;
    }

    理解:

    KMP思想:配对不成功时,将最大前缀与后缀对齐,从而减少匹配次数。

    next数组的作用:配对不成功时,子串指针移动到最大前缀的最后一个值的下一个位置,就是next的值。

    int buildNext(){
        Next[0]=-1;
        int i;
        for(int j=1;j<m;j++){
            i=Next[j-1];//存储最大前缀的最后一个值的下标
            while((i>=0)&&(s2[i+1]!=s2[j])){//若当前前缀不符合,则回退,找寻次大的前缀
                i=Next[i];
            }
            if(s2[i+1]==s2[j]){
                Next[j]=i+1;
            }
            else{//i<0,不存在前缀
                Next[j]=-1;
            }
        }
    }

    递推方式求解next,如下图:如果在j-1配对的基础上,如果match[j-1]+1与j的字符相等,则可以直接:match[j]=match[j-1]+1  (可以通过反证法证明)

    如果不相等,则讲 i 回退,找次小的前缀。while里面是前缀递减的过程

  • 相关阅读:
    软件测试人员的年终绩效考核怎么应对
    收藏
    顶踩组件 前后两版
    订阅组件
    hdu 1963 Investment 完全背包
    hdu 4939 Stupid Tower Defense 动态规划
    hdu 4405 Aeroplane chess 动态规划
    cf 414B Mashmokh and ACM 动态规划
    BUPT 202 Chocolate Machine 动态规划
    hdu 3853 LOOPS 动态规划
  • 原文地址:https://www.cnblogs.com/dreamzj/p/14604276.html
Copyright © 2011-2022 走看看