zoukankan      html  css  js  c++  java
  • 关于KMP算法的重大发现

    之前写KMP模板的时候,nx[i]代表最大的一个x,使s[1,x-1]是s[1,i-1]的后缀。(方法1)

    然而网上还有另一种方法求nx数组,nx[i]表示最大的一个x,使s[1,x]是s[1,i]的后缀。(方法2)

    两种nx数组在具体匹配的时候方法稍有不同,但都能正确匹配字符串。

    但是在做字符串DP题的时候,发现网上的题解大多是利用第二种nx数组的性质进行状态的转移。

    当时试着写了一下那种nx的求法,但是觉得很别扭,用不惯也记不住。

    不知所措。

    今天看了一下洛谷的KMP模板(P3375)(传送门),发现得求出第二种nx数组......

    这回把第二种求法忘了,也很反感那么写。

    于是立志要找出两种方法的联系。

    很简单嘛:nx2[i]=nx1[i+1]-1

    同时,getnx的时候要走到m+1(m为模式串长),这样nx[m+1]才有值。

    给一个洛谷P3375的代码。

    注意getnx的改动和最后要求输出nx数组的时候是怎么操作的。

     1 #include<cstdio>
     2 #include<cstring>
     3 
     4 char s1[1000005],s2[1000005];
     5 int nx[1000005];
     6 int pos[1000005],cnt;
     7 int n,m;
     8 
     9 void getnx()
    10 {
    11     nx[1]=0;
    12     for(int i=2,j=1;i<=m+1;)
    13     {
    14         nx[i]=j;
    15         while(j&&s2[i]!=s2[j])j=nx[j];
    16         i++,j++;
    17     }
    18 }
    19 
    20 void kmp()
    21 {
    22     for(int i=1,j=1;i<=n;)
    23     {
    24         while(j&&s1[i]!=s2[j])j=nx[j];
    25         if(j==m)
    26         {
    27             pos[++cnt]=i-m+1;
    28             j=nx[j];
    29         }
    30         else i++,j++;
    31     }
    32 }
    33 
    34 int main()
    35 {
    36     scanf("%s",s1+1);
    37     scanf("%s",s2+1);
    38     n=strlen(s1+1);
    39     m=strlen(s2+1);
    40     getnx();
    41     kmp();
    42     for(int i=1;i<=cnt;i++)printf("%d
    ",pos[i]);
    43     for(int i=1;i<=m;i++)printf("%d ",nx[i+1]-1);
    44     return 0;
    45 }
  • 相关阅读:
    animate动画回调函数
    triggerHandler不执行事件默认值
    trigger自动执行事件
    js与jquery对象的互转
    让低版本浏览器支持html5的标签
    闭包的好处罗列
    AJAX跨域
    php能干什么?
    concat() 方法用于连接两个或多个数组。
    使用 v-cloak 防止页面加载时出现 vuejs 的变量名
  • 原文地址:https://www.cnblogs.com/cervusy/p/9651420.html
Copyright © 2011-2022 走看看