• Period HDU 1358 KMP next数组性质的应用


    Period HDU 1358 KMP next数组性质的应用

    原题链接

    题意

    题目的意思是给你一个字符串,判断这个字符串的前缀字符串中,哪些是周期串,输出这个前缀字符串的长度和这个前缀字符串中循环节的个数。

    解题思路

    思路参考:https://www.cnblogs.com/yym2013/p/3586495.html

    这道题考察的是KMP算法中next数组的应用,必须理解透next[]数组代表的含义才能通过它解决这道题。
    思路是先构造出 next[] 数组,下标为 i,定义一个变量 j = i - next[i] 就是next数组下标和下标对应值的差,如果这个差能整除下标 i,即 i%j==0 ,则说明下标i之前的字符串(周期性字符串长度为 i)一定可以由一个前缀周期性的表示出来,这个前缀的长度为刚才求得的那个差,即 j,则这个前缀出现的次数为 i/j 。所以最后输出i和i/j即可。

    注意:这里求next的算法不能是那种简化形式的。

    这里需要特殊处理的是next[i] = 0或者next = -1要忽略。

    代码实现

    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<iostream>
    #include<string>
    #include<stack>
    #include<queue>
    #include<map>
    using namespace std;
    const int MAXN=1e6+7;
    char s[MAXN];
    int  nx[MAXN], n;
    void get_next()
    {
    	int j=0, k=-1, len=n; 
    	nx[0]=-1;
    	while(j<len)
    	{
    		if(k == -1 || s[j] == s[k])
    		{
    			j++; k++;
    			nx[j] = k; 
    		}
    		else k = nx[k];
    	}
    }
    int main()
    {
    	int count=1;
    	while( scanf("%d", &n)  && n!=0)
    	{
    		int j=0;
    		scanf("%s", s);
    		get_next();
    		printf("Test case #%d
    ", count++);
    		for(int i=2; i<=n; i++)
    		{
    			if(nx[i] <= 0)
    				continue;
    			j = i - nx[i];
    			if(i % j == 0)
    				printf("%d %d
    ", i, i/j);
    		}
    		printf("
    ");
    	}
    	return 0;
    }
    
    欢迎评论交流!
  • 相关阅读:
    ts笔记-辨析联合类型
    ts笔记-类型兼容性
    ts笔记-never和void
    ts笔记-泛型
    ts笔记-类型断言
    ts笔记
    ts笔记
    ts类型-枚举
    ts笔记-类型声明
    ts笔记-类型系统
  • 原文地址:https://www.cnblogs.com/alking1001/p/12243767.html
Copyright © 2020-2023  润新知