zoukankan      html  css  js  c++  java
  • 【hdoj】1358 Period【字符串--最小循环节 i/next[i]即为其长度】

    传送门:Period

    题意

    给出一个字符串,从第二个位置开始找到它前缀的最大重复次数及及此时的位置

    分析

    利用KMP的next数组求解。根据next数组的定义(当前位置的前缀后缀最大匹配长度)
    发现在位置i处如果出现了重复,必有i-next[i]为前缀最大的重复长度,此时满足(i%(i-next[i])==0),且重复的次数为(i/(i-next[i]))

    My AC Code

    #include<bits/stdc++.h>
    #define rep(i,a,b) for(int i=a;i<=b;i++)
    using namespace std;
    const int maxn=1e6+5;
    
    char source[maxn];
    char pattern[maxn];
    int NEXT[maxn];
    
    int bf(char* source,char *pattern )
    {
    	int n=strlen(source);
    	int m=strlen(pattern);
    	int i=0;
    	int j=0;
    	while(i<n&&j<m)
    	{
    		if(source[i]==pattern[j])
    		{
    			i++;
    			j++;
    		}
    		else
    		{
    			i=i-j+1;
    			j=0;			
    		}
    	}
    	if(j==m)
    		return i-j;
    	else
    		return -1;
    }
    
    void GetNext()
    {
    	int pLen = strlen(pattern);
    	NEXT[0] = -1;
    	int k = -1;
    	int j = 0;
    	while (j < pLen)
    	{
    		//p[k]表示前缀,p[j]表示后缀
    		if (k == -1 || pattern[j] == pattern[k]) 
    		{
    			++k;
    			++j;
    			NEXT[j] = k;
    		}
    		else 
    		{
    			k = NEXT[k];
    		}
    	}
    }
    
    
    void kmp()
    {	
    	GetNext();
    	int m=strlen(pattern);
    	for(int i=2;i<=m;i++)
    	{
    		//i-NEXT[i] 为最小循环节的长度
    		if(i%(i-NEXT[i])==0&&NEXT[i]>0)
    		{
    			printf("%d %d
    ",i,i/((i-NEXT[i])));
    		}		
    	}
    }
    
    
    
    
    
    int main()
    {	
    	int t;
    	int cnt=1;	
    	while(scanf("%d",&t)&&t)
    	{
    		scanf("%s",pattern);
    		printf("Test case #%d
    ",cnt++);
    		kmp();		
    		printf("
    ");
    	}
        return 0;
    }
    
  • 相关阅读:
    10/28总结
    10/27总结
    10/26总结
    10/25总结
    10/24总结
    毕业设计第二周整理规划
    毕业设计第一周第五天完成情况汇总
    毕业设计第一周第四天完成情况汇总
    毕业设计第一周第三天完成情况汇总
    毕业设计第一周第二天完成情况汇总
  • 原文地址:https://www.cnblogs.com/shengwang/p/9780760.html
Copyright © 2011-2022 走看看