• poj_2406 kmp


    题目大意

        给出一个字符串S,S可能是多个较短的字符串的重复连接。比如"ababab"为字符串"ab"重复三次的结果;"abc" 为"abc"重复一次的结果;"abababab"可能是"abab"重复两次,也可能是"ab"重复四次的结果。 
        对一个给定的字符串S,求出最大的k,使得它为某个子串A重复k次的结果。

    题目分析

        有了kmp的next数组(存储某子串的最长相同前后缀的长度),可以在此基础上分析。字符串S的子串A越短,则重复次数越多。 
        (1)显然,对于一个最多含有K个重复的A构成的串S,S的最长相同前后缀S1为K-1个A重复的结果; 
        (2)若S的最长相同前后缀S1和S确定的剩余部分S-S1(记为子串B)不能通过多个连接起来形成S1或者S,那么S必定无法分解为多个子串相连接的结果。 
        证明性质(2),若S-S1(记为A)不能拼成S或者S1,而S可以由多个子串拼接而成。假设S由P(不是最大的)个相同的子串B构成,那么P-1个B连接起来一定为S的相同前后缀(不一定为最长相同前后缀),且该相同前后缀的长度必定大于 strlen(S)/2,则strlen(S1)必定大于strlen(S)/2,则S的最长相同前后缀在S中必定相交! 
        对于串S,若他的最长前后缀相交,则可以肯定 S 由K个(S-S1)拼接而成。(通过画图可以说明)

    实现(c++)

    #define _CRT_SECURE_NO_WARNINGS
    #define MAX_WORD_LEN  1000005
    #include<stdio.h>
    #include<string.h>
    int gNext[MAX_WORD_LEN];
    char gWord[MAX_WORD_LEN];
    int gLength[MAX_WORD_LEN];
    void GenerateNext(const char* sub_str, int* next, int len){
    	next[0] = 0;								//next[i]表示sub_str[0, i]中最长相同前后缀的长度
    	for (int i = 1; i < len; i++){
    		int j = next[i - 1];
    		while (sub_str[j] != sub_str[i]){		//不断回溯,每次利用next数组来确定下一个需要判断的位置
    			if (j == 0){
    				j = -1;
    				break;
    			}
    			j = next[j - 1];
    		}
    		if (j < 0)
    			next[i] = 0;
    		else
    			next[i] = j + 1;
    	}
    }
    
    int main(){
    	while (scanf("%s", gWord) != EOF){
    		if (strcmp(gWord, ".") == 0){
    			break;
    		}
    		int len = strlen(gWord);
    		GenerateNext(gWord, gNext, len);
    		if (len % (len - gNext[len - 1]) == 0){
    			printf("%d
    ", len / (len - gNext[len -1]));
    		}
    		else
    			printf("1
    ");		
    	}
    	return 0;
    }
    
  • 相关阅读:
    django2.2/mysql ImproperlyConfigured: mysqlclient 1.3.13 or newer is required; you have 0.9.3
    orm练习题
    url的匹配问题
    集成抽象类后出现的问题
    迅为IMX6Q开发板上移植mplayer
    迅为i.MX6ULL开发板原理图分析介绍
    性价比高又能较好的学习嵌入式ARM+Linux的开发板
    适合初学者的linux开发板
    IMX6ULL开发板
    i.MX6ULL开发板终结者资料介绍
  • 原文地址:https://www.cnblogs.com/gtarcoder/p/4813794.html
Copyright © 2020-2023  润新知