来源:《算法竞赛入门经典》例题5.1.3
题目:如果一个字符串可以由某个长度为k的字符串重复多次得到,我们说该串以k为周期。例如,abcabcabcabc以3为周期(注意,它也以6和12为周期)。输入一个长度不超过80的串,输出它的最小周期。
样例输入:HoHoHo
样例输出:2
分析:题目中说过,字符串可能会有多个周期。但因为只需求出最小的一个,可以从小到大枚举各个周期,一旦符合条件就立即输出。
源码:
#include<stdio.h> #include<string.h> int main() { char word[100]; int len,i,j,ok; scanf("%s",word); len = strlen(word); for(i=1;i<=len;i++) //假设最小周期(最小周期串长度)为i { if(len%i==0) //字符串长度一定是周期的倍数 { ok=1; for(j=i;j<len;j++) //从周期i的下一个位置j(因为数组是从0开始的,所以下一个位置的索引j等于周期i)开始 if(word[j]!=word[j%i]) //和前面假设的周期串中字符逐个比较 { ok=0; //如果发现出现一个不相等了,说明这个i不是周期 break; //退出循环比较,递增假设的周期i } if(ok) //循环比较完,仍找不到不相等的就可以确定i是最小周期 { printf("%d ",i); break; } } } return 0; }
来说明一下上面的代码,首先我们假设这个周期串的长度为i,则根据这个word的长度,我们这个周期串的周期可能是1,2,3,4,...,len。所以外面套一个for循环从小到大遍历各种可能的周期,然后我们从周期长度的下一个位置开始循环和这个假设的周期串中对应的字符逐个的比较,如果出现一个不相等了,说明这个不是周期串。这样说还是有点抽象,我们来看一下下面的图:
由上图可以清楚的看出,j=4的时候j%i=0,所以word[4]必须要和word[0]相等,以此类推可以知道必须有word[5]=word[1],word[6]=word[2]...word[j]=word[j%i]才能确定i是字符串的周期