字符串移位包含的问题 结构之法 1
给定两个字符串s1和s2,要求判定s2是否能够被s1做循环移位(rotate)得到的字符串包含。例如,给定s1=AABCD和s2=CDAA,返回true;给定s1=ABCD和s2=ACBD,返回false。
解法一:
从题目中可以看出,我们可以使用最直接的方法对s1进行循环移位,再进行字符串包含判断,从而遍历其所有的可能性。
若字符串的长度N较大,显然效率很低。
解法二:
我们可以对循环移位之后的结果进行分析。
假设我们把前面移走的数据进行保留,会发现有如下的规律:
ABCD ->ABCDA ->ABCDAB ->ABCDABC ->ABCDABCD
因此,可以看出对s1做循环移位(rotate)所得到的字符串都是将字符串s1s1的子字符串。如果s2可以由s1循环移位(rotate)得到,那么s2一定在s1s1上。至此我们将问题转换成考察s2是否在s1s1上,可以通过调用一次strstr函数得到结果。
例如若CDAB在ABCDABCD上,那么CDAB也可通过ABCD做循环移位得到。
解法二利用了“提高空间复杂度来换取时间复杂度的降低”的思路,适用于对时间复杂度要求高的场合。
strstr函数说明:
原型: extern char* strstr(char *haystack, char *needle);
用法:#include<string.h>
功能:从字符串haystack中寻找needle第一次出现的位置(不比较结束符NULL)
说明:返回指向第一次出现needle位置的指针,如果没找到则返回NULL
#include<iostream>
#include<string.h>
using namespace std;
int main()
{
//char src[]="AABBCD"; //源s1
//char des[]="CDAA"; //目的s2
char src[20];
char des[10];
cout<<"请输入源字符串"<<endl;
cin>>src;
cout<<"请输入目的字符串"<<endl;
cin>>des;
char tmp[100];
strcpy(tmp,src);
strcat(tmp,src);
cout<<tmp<<endl;
int len=strlen(src);
int i=0;
while(i<2*len)
{
if(strstr(tmp,des)!=NULL) break;
i++;
}
if(i==2*len) cout<<"FALSE"<<endl;
else cout<<"TRUE"<<endl;
return 0;
}