zoukankan      html  css  js  c++  java
  • KMP

    Algorithm Desciption

    KMP算法是一个用于解决A串是否是B串的子串的问题。这个算法的核心在于当出现不匹配的状态的时候,并不是直接跳回到0的位置上面去,而是去寻找这个已匹配的串中,前缀和后缀相等的长度。(当然如果前缀和后缀不相等,还是0)
    用图来解释比如说现在失配了(1,2,3,4这四个段完全相同)

    然后就这么跳

    图画的丑,不要在意

    而怎么跳呢,就需要自己去处理出一个Nxt数组了

    Description

    给定若干长度小于等于1000000的字符串,询问每个字符串最多由多少个相同的子串重复连接而成(循环节),例如ababab,最多由3个ab连接而成

    Input

    若干行,每行一个字符串。最后一行是一个"."点号,作为输入的结尾

    Output

    对应输入的每行,计算最多有多少个相同子串连接而成

    Sample Input

    abcd 
    aaaa 
    ababab 
    .
    

    Sample Output

    1 
    4 
    3
    

    Analysis

    这一道题直接来看的话好像和KMP算法没有什么关系,但是通过KMP算法确实是可以做这一道题的。

    对于输入的字符串,它的Nxt值有两种结果

    1.最后一个数的前缀长度加上后缀长度大于他自己的长度。这意味着它最长的相同的前缀后缀之间有重叠的地方,如图

    这样的话,就容易得出答案为(tdiv(t-Nxt[t-1]))(t是字符串的长度)

    2.如果说没有重合,那么就直接是1就好了

    Code

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define maxn 1000002
    
    using namespace std;
    
    char c[maxn];
    int k[maxn];
    
    void init();
    
    int main(){
    	scanf("%s",c);
    	while(c[0]!='.'){
    		init();
    		int t=strlen(c);
    		if(!(t%(t-k[t-1])))printf("%d
    ",t/(t-k[t-1]));
    		else printf("1
    ");
    		scanf("%s",c);
    	}
    }
    
    void init(){
    	int t=strlen(c);
    	k[0]=0;
    	for(int i=1,j=0;i<t;i++){
    		while(j>0&&c[i]!=c[j])j=k[j-1];
    		if(c[i]==c[j])j++;
    		k[i]=j;
    	}
    }
    
    
  • 相关阅读:
    正则表达式
    特殊符号作用
    sed
    scp
    EOF
    env
    JAVA进阶5
    JAVA进阶4
    JAVA进阶3
    JAVA进阶2
  • 原文地址:https://www.cnblogs.com/perisino/p/10547206.html
Copyright © 2011-2022 走看看