问题描述:
给定两个字符串S1和S2,要求判定S2是否能够被S1做循环移动得到的字符串包含。如S1=AABCD和S2=CDAA,则S1循环移动后包含S2,返回true;S1=ABCD和S2=ACBD,则S1循环移动后不包含S2,返回false
解题思路:
1)可以发现,S1循环移动后的结果肯定包含在字符串S1+S1中,所以可以直接判断S2是否包含在字符串S1+S1中,这样需要的空间复杂度较大,但是只需要做一次contains的查询,时间复杂度较小。 (参考《编程之美》)
2)可以把字符串S1看做一个循环列表,这样只要重新设计contains函数就可以,空间复杂度和时间复杂度都很小。
代码如下:
/**
*@author MWD
* 2013-9-20
*/
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
bool rotateContain1(char*,char*);
bool rotateContain2(char*,char*);
int main(){
char src[] = "AABBCD";
char des[] = "CDAA";
bool flag1 = rotateContain1(src,des);
bool flag2 = rotateContain2(src,des);
if(flag1 == true)
printf("rotatecontain1 find!\n");
else
printf("rotateContain1 can not find!\n");
if(flag2 == true)
printf("rotatecontain2 find!\n");
else
printf("rotateContain2 can not find!\n");
getchar();
return 0;
}
/**
* 可以将问题转化为判断des是否在字符串src+src中,增加了空间复杂度,减小了时间复杂度
*/
bool rotateContain1(char* src,char* des){
int len1 = strlen(src);
int len2 = strlen(des);
char * str = (char*)malloc(sizeof(char)*(2*len1));
int i=0;
for(int j=0;j<len1;j++){
str[i++] = src[j];
}
for(int j =0;j<len1;j++)
str[i++] = src[j];
if(strstr(str,des)!= NULL)
return true;
else
return false;
}
/**
* 可以将
*/
bool rotateContain2(char* src,char* des){
int len1 = strlen(src); //字符串src的长度
int len2 = strlen(des); //字符串des的长度
int j,k;
if(!len2)
return true;
for(int i=0;i<len1;i++){
j = 0;
//如果第一个字符相等,那么就继续比较剩下的字符
if(src[i] == des[j]){
for(;j<len2;j++){
k = (i+j)%len1; //将循字符数组看做循环列表
if(src[k] != des[j])
break;
}
if(j == len2)
return true;
else
return false;
}
}
//比较完所有的字符,没有找到包含,那么就不存在包含关系
return false;
}