给定两个字符串s1和s2,要求判断s2是否能够被通过s1做循环移位(rotate)得到的字符串包含。例如,S1=AABCD和s2=CDAA,返回true;给定s1=ABCD和s2=ACBD,返回false。
1. 最直接的方法对S1进行循环移位,遍历所有可能性。
#include <iostream>
using namespace std;
void main()
{
char s1[]="AABCD";
char s2[]="CDAA";
int len=strlen(s1);
for (int i=0;i<len;i++)
{
char temp=s1[0];
for (int j=0;j<len-1;j++)
s1[j]=s1[j+1];
s1[len-1]=temp;
if(strstr(s1,s2)!=NULL) //strstr() 函数搜索一个字符串在另一个字符串中的第一次出现。找到所搜索的字符串,则该函数返回第一次匹配的字符串的地址;如果未找到所搜索的字符串,则返回NULL。
{
cout<<"true";
break ;
}
}
}
2. 我们也可以对循环移位之后的结果进行分析。
以S1 = ABCD为例,先分析对S1进行循环移位之后的结果,如下所示:
ABCD--->BCDA---->CDAB---->DABC---->ABCD……
假设我们把前面的移走的数据进行保留,会发现有如下的规律:
ABCD--->ABCDA---->ABCDAB---->ABCDABC---->ABCDABCD……
因此,可以看出对S1做循环移位所得到的字符串都将是字符串S1S1的子字符串。如果S2可以由S1循环移位得到,那么S2一定在S1S1上,这样时间复杂度就降低了。
#include <iostream>
#include <string>
using namespace std;
void main()
{
string s1="AABCD";
string s2="CDAA";
s1=s1+s1;
if(strstr(s1.c_str(),s2.c_str())!=NULL)
cout<<"true";
}