zoukankan      html  css  js  c++  java
  • 扩展kmp--模板解析

    扩展kmp:

      用于求串的各个后缀与原串的最长公共前缀的长度;

    上图的是字符串自匹配的过程:

    图一:

        假设现在匹配到i-1了,开始求next [ i ] 的值,此时,k记录的是到目前为止匹配到的最远的位置的那一次的起点,p标志的是已经匹配过的最远的点;

    图二:

        因为前面是匹配过的,所以可以知道,k~p和源串的1~b是一模一样的,所以 i 匹配的前一段可以和k~p段直接匹配,而不用和源串匹配,如果i匹配完成后,从i开始next[ i ]长度是和源串一模一样的。这个时候可以看图三。

    图三:

        可以看到 i 与 k 的相对位置和a 与 1 的相对位置是一样的,而且1~a与k~i之间的是一样的,i与a也是一样的,而且next[ a ]是已经计算过的,所以用l = next[ i - k ]

    p=k+next[ k ];   然后  if ( l<p)就是当用之前的匹配结果没有匹配超出p那么就可以直接用之前的结果了:next[ i ]=l;如果超出了p的范围,就要把超出的部分匹配一下,然后要更新k;

    这样自匹配就结束了;

    然后是字符间匹配,过程几乎一模一样;不再详述;

    代码如下;

     1 #include<iostream>
     2 #include<cstdio>
     3 using namespace std;
     4 string a,b;//a串和b的所有后缀匹配可以匹配的最长长度;
     5 int m,n;//m,是a串的长度;n是b串的长度;
     6 int Next[100000],ret[100000];//Next数组是自匹配,ret是串间匹配;
     7 
     8 void ExtendKmp()
     9 {
    10     int i,j,k;
    11     for( j=0;j+1<m&&a[j]==a[j+1];j++);
    12     Next[1]=j;
    13     k=1;
    14     for( i=2;i<m;i++)
    15     {
    16         int p=k+Next[k],l=Next[i-k];
    17         if(l+i<p)
    18             Next[i]=l;
    19         else
    20         {
    21             for(j = max(0,p-i);j<m&&i+j<m&&a[j]==a[i+j];j++);
    22             Next[i]=j;
    23             k=i;
    24         }
    25     }
    26     for(j=0;j<n&&j<m&&a[j]==b[j];j++);
    27     ret[0]=j;
    28     k=0;
    29     for( i=1; i<n; i++)
    30     {
    31         int p=k + ret[k],l=Next[i-k];
    32         if(l+i<p)
    33             ret[i]=l;
    34         else
    35         {
    36             for(j =max(0,p-i);j<m&&i+j<n&&a[j]==b[i+j];j++);
    37             ret[i]=j;
    38             k=i;
    39         }
    40     }
    41 }
    42 
    43 int main()
    44 {
    45     cin>>a>>b;
    46     m=a.size();
    47     n=b.size();
    48     ExtendKmp();
    49     for(int i=0;i<n;i++)
    50         cout<<ret[i]<<' ';
    51     cout<<endl;
    52     return 0;
    53 }
  • 相关阅读:
    Oracle 安装安全补丁过程中出现的问题
    Oracle 设置日志模式
    Oracle 设置archivelog错误解决方案
    sum() over() 函数的使用
    C盘清理,移动node 依赖和缓存文件
    ol设置最佳可视范围和限制缩放
    flex弹性布局模式下文字超出显示省略号
    查看svn本地账户和密码
    flutter apk启动闪退问题
    More than one file was found with OS independent path 'lib/armeabi-v7a/libflutter.so'
  • 原文地址:https://www.cnblogs.com/by-1075324834/p/4525743.html
Copyright © 2011-2022 走看看