Openjudge-NOI题库-字符串移位包含问题
- 题目描述 Description
-
对于一个字符串来说,定义一次循环移位操作为:将字符串的第一个字符移动到末尾形成新的字符串。
给定两个字符串s1和s2,要求判定其中一个字符串是否是另一字符串通过若干次循环移位后的新字符串的子串。例如CDAA是由AABCD两次移位后产生的新串BCDAA的子串,而ABCD与ACBD则不能通过多次移位来得到其中一个字符串是新串的子串。
- 输入输出格式 Input/output
- 输入:
- 一行,包含两个字符串,中间由单个空格隔开。字符串只包含字母和数字,长度不超过30。
- 输出:
- 如果一个字符串是另一字符串通过若干次循环移位产生的新串的子串,则输出true,否则输出false。
- 输入输出样例 Sample input/output
样例测试点#1
- 输入样例:
- AABCD CDAA
- 输出样例:
- true
- 说明 description
结果可能很大!
思路:
我们可以对循环移位之后的结果进行分析。
以S1 = ABCD为例,先分析对S1进行循环移位之后的结果,如下所示:
ABCD--->BCDA---->CDAB---->DABC---->ABCD……
假设我们把前面的移走的数据进行保留,会发现有如下的规律:
ABCD--->ABCDA---->ABCDAB---->ABCDABC---->ABCDABCD……
因此,可以看出对S1做循环移位所得到的字符串都将是字符串S1S1的子字符串。如果S2可以由S1循环移位得到,那么S2一定在S1S1上,这样时间复杂度就很低,而且又快速。
以S1 = ABCD为例,先分析对S1进行循环移位之后的结果,如下所示:
ABCD--->BCDA---->CDAB---->DABC---->ABCD……
假设我们把前面的移走的数据进行保留,会发现有如下的规律:
ABCD--->ABCDA---->ABCDAB---->ABCDABC---->ABCDABCD……
因此,可以看出对S1做循环移位所得到的字符串都将是字符串S1S1的子字符串。如果S2可以由S1循环移位得到,那么S2一定在S1S1上,这样时间复杂度就很低,而且又快速。
代码如下:
1 #include<iostream> 2 using namespace std; 3 int fun(string src,string des) 4 { 5 string tmp = src; 6 src=src+tmp; 7 if(strstr(src.c_str(),des.c_str())==NULL)//指向字符串str2 首次出现于字符串str1中的位置,如果没有找到,返回NULL。 8 { 9 return 0; 10 } 11 return 1; 12 } 13 int main() 14 { 15 int i=0,j=0; 16 char a[31]; 17 char b1[31],b2[32]; 18 /*=======================*/ 19 gets(a); 20 while(a[i]!=' ') 21 { 22 b1[i]=a[i]; 23 i++; 24 } 25 b1[i]='\0'; 26 i++; 27 while(a[i]!='\0') 28 { 29 b2[j]=a[i]; 30 i++; 31 j++; 32 } 33 b2[j]='\0'; 34 /*=======================*///空格分开存储 35 if(fun(b1,b2)==1) 36 printf("true\n"); 37 else 38 printf("false\n"); 39 }
我不怕千万人阻挡,只怕自己投降…