UVA455周期串
- 代码a(c):
#include<string.h>
2 #include<stdio.h>
3
4 int main()
5 {
6 //定义一个字符串数组
7 char yuan[100] = {0}; //存放输入的字符串
8 int n;
9 printf("give the words:\n");
10 scanf("%d",&n); //从键盘输入要输入几个字符,用while遍历
11 int l;
12 int j;
13 while(n--){
14 scanf("%s",yuan); //ABCABEABCABCE //将从键盘输入的字符放入yuan数组中
15 l = strlen(yuan); //l=6 //得出yuan的字符串数组长度
16 for(int i=1;i<l;i++) //
17 {
18 if(l% == 0) //假如原字符串长度是i的倍数,说明有可能是一个循环节,继续判断
19 {
20 //1.判断后一个字符是否和前一个字符相等,假如不相等,继续判断
21 //这句if相当与把yuan数组遍历的一次而且最后超出了原来的内容一位
22 for(j=i;j<l;j++)
23 {
24 if(yuan[j]!=yuan[j%i])
25 break;
26 } //再定义j也控制在l的长度之内,假如yuan的下一个字符内容
27 } //不等于yuan的上个字符内容,就跳出循环
28 //2.判断这个字符现在的长度是否等于输入字符的长度,假如相等说明已经到了字符的长度,就可以输出循环节部分
29 if(j==l){ //j表示扫描到的第几个字符
30 printf("the length is:%d\n",i); //就输出i,i表示循环节长度
31 //为什么用break跳不出循环?
32 i=l;
33 }
34 }
35 }
36
37 return 0;}
- 代码b(c++):
#include<iostream>
#include<string>
using namespace std;
int main(){
string s,k;
//s是原来字符串,k是重复的字符串
int n;
cin>>n;
while(n--){
cin>>s;
k="";//别忘了初始化!
for(int i=0;i<s.length();i++){
k+=s[i];//在k的后面加上s中的下一项
if(s.length()%k.length()==0){ //如果能整除(就是重复可以正好凑齐)
int t=s.length()/k.length();
//t是循环几次
string k2;//k2用来比较
for(int j=0;j<t;j++){
k2+=k;//k2一直累加到长度与s相同
}
if(k2==s){//判断是否相同
cout<<k.length()<<endl;
//输出长度
i=s.length();
//跳出循环的搞笑方法
if(n)cout<<endl;
//自己看格式
}
}
}
}
return 0;
}
心得:
我认为这个题的两种算法思路的核心都是比较,但两者代码的比较内容是不同的。
代码a中我认为核心是定义了一个i变量来表示循环节和一个j变量表示遍历到的长度,if(yuan[j]!=yuan[j%i]);这句十分精彩,因为i是循环节所以当j对i取余时,余数是不会超过i的,如图:
,所以通过取余可以求出i,并且在比较的时候逐个字符会按照循环节i来进行轮回比较,直到最后一轮j=l。
代码b中,首先体现了c++的优越性和方便性,我认为核心是进行了一个字符串的赋值比较,int t=s.length()/k.length();
//t是循环几次
string k2;//k2用来比较
for(int j=0;j<t;j++){
k2+=k;//k2一直累加到长度与s相同
}
这一步比较精彩,k2的值是局部变量,在第一轮执行这个循环的时候程序会得到一个全是相同的字母的字符串如:
abcabceabcabce 12 i=3
i=0 s.len =12 k.len =1 k="a“ k2=k2+k aaaaaaaaaa
但是aaaaaaaaaaaaaa和原字符串 abcabceabcabce不相同,于是i+1再将第二个字符送给k,此时再执行到这一步时,k2是又一次重新被定义了的,直到最后k2和s字符串内容相同,收获颇丰。
积土成山,风雨兴焉,继续学习。(代码b转自洛谷用户:sss7020)
(以上所有内容均为学习内容,如有侵权立即删除)