zoukankan      html  css  js  c++  java
  • wenbao与扩展kmp

    给定两个字符串S和T(长度分别为n和m),下标从0开始,定义extend[i]等于S[i]...S[n-1]与T的最长公共前缀的长度,求出所有的extend[i]

    next[i]: T[i]...T[m-1]与T的最长公共前缀长度;
    extend[i]: S[i]...S[n-1]与T的最长公共前缀的长度。

    推荐博客:https://wenku.baidu.com/view/8e9ebefb0242a8956bece4b3.html

     1 //C/C++ 模板
     2 #include <iostream>
     3 #include <stdio.h>
     4 #include <string.h>
     5 using namespace std;
     6 const int N = 101010;
     7 int next[N],extand[N];
     8 void getnext(char *T){// next[i]: 以第i位置开始的子串 与 T的公共前缀 
     9     int i,length = strlen(T);
    10     next[0] = length;
    11     for(i = 0;i<length-1 && T[i]==T[i+1]; i++); //单独处理next[1]
    12     next[1] = i;
    13     int a = 1;
    14     for(int k = 2; k < length; k++){
    15         int p = a+next[a]-1, L = next[k-a];
    16         if( (k-1)+L >= p ){
    17             int j = (p-k+1)>0? (p-k+1) : 0; 
    18             while(k+j<length && T[k+j]==T[j]) j++;// 枚举(p+1,length) 与(p-k+1,length) 区间比较 
    19             next[k] = j, a = k;
    20         } 
    21         else next[k] = L;
    22     } 
    23 }
    24 void getextand(char *S,char *T){
    25     memset(next,0,sizeof(next)); 
    26     getnext(T); 
    27     int Slen = strlen(S), Tlen = strlen(T), a = 0;
    28     int MinLen = Slen>Tlen?Tlen:Slen;
    29     while(a<MinLen && S[a]==T[a]) a++;
    30     extand[0] = a, a = 0;
    31     for(int k = 1; k < Slen; k++){
    32         int p = a+extand[a]-1, L = next[k-a];  
    33         if( (k-1)+L >= p ){
    34             int j = (p-k+1)>0? (p-k+1) : 0; 
    35             while(k+j<Slen && j<Tlen && S[k+j]==T[j] ) j++; 
    36             extand[k] = j;a = k; 
    37         } 
    38         else extand[k] = L;         
    39     }
    40 }
    41 
    42 int main(){
    43     char s[N],t[N];
    44     while(~scanf("%s %s",s,t)){
    45         getextand(s,t); 
    46         for(int i = 0; i < strlen(t); i++) printf("%d ",next[i]);
    47         puts(""); 
    48         for(int i = 0; i < strlen(s); i++) printf("%d ",extand[i]);
    49         puts("");
    50     } 
    51 }
    52 
    53 /*
    54 abababab abab
    55 aaaabaaa aaaa
    56 */

    只有不断学习才能进步!

  • 相关阅读:
    Android中手机录屏并转换GIF的两种方式
    Android中访问sdcard路径的几种方式
    Android中开发工具Android Studio修改created用户(windows环境)
    [UOJ211][UER #6]逃跑
    [CF1168D]Anagram Paths
    [CF852H]Bob and stages
    Codechef BINOMSUM
    [ZJOI2019]开关
    [CF1161F]Zigzag Game
    [CF1149E]Election Promises
  • 原文地址:https://www.cnblogs.com/wenbao/p/7146013.html
Copyright © 2011-2022 走看看