字符串移位包含的问题

问题描述:给定两个字符串s1和s2,要求判定s2是否能够被s1做循环移位(rotate)得到的字符串包含。例如,给定s1=AABCD和s2=CDAA,返回true;给定s1=ABCD和s2=ACBD,返回false。

解法一:对s1进行循环移位,再进行字符串包含的判断,从而遍历其所有可能性。

#include<stdio.h>
#include<string.h>

int rotate_conbine(char *src, char *des);

int main(){
	
	char src[] = "AABBCD";
	char des[] = "CDAA";
	
	if(rotate_conbine(src, des))
		printf("src rotate contain des\n");
	else
		printf("scr donot contain des\n");
	return 0;
}

int rotate_conbine(char *src, char *des){
int len = strlen(src);
for(int i=0; i<len; i++){
char temp = src[0];
for(int j=0; j<len -1; j++)
src[j] = src[j+1];
src[len-1] = temp;
if(strstr(src, des) != NULL)
return 1;
}
return 0;
}


解法二:对s1做循环移位(rotate)所得到的字符串都将是字符串s1s1的子字符串。如果s2可以由s1循环移位(rotate)得到,那么s2一定在s1s2上。至此我们将问题转换成考察s2是否在s1s1上,可通过调用一次strstr函数得到结果。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

int doubel_src_conbine(char *src, char *des);

int main(){
	
	char src[] = "AABBCD";
	char des[] = "CDAB";
	if(doubel_src_conbine(src, des))
		printf("src rotate contain des\n");
	else
		printf("scr donot contain des\n");
	return 0;
}

int doubel_src_conbine(char *src, char *des){
	int len = strlen(src);
	char *temp = (char *)malloc((2*len+1)*sizeof(char));
	char *p = temp;
	char *s = src;
	while(*s != '\0'){
		*p = *s;
		p++;
		s++;
	}
	s = src;
	while(*s != '\0'){
		*p = *s;
		p++;
		s++;
	}
	p++;
	*p = '\0';
	if(strstr(temp, des) != NULL)
		return 1;
	else
	    return 0;
}


解法三:第二种方法利用了“提高空间复杂度来换取时间复杂度的降低”的思路,适用于对时间复杂度要求高的场合。能否不需要申请过多新的空间,解决这个问题。可以用指针的方法做到。

#include<stdio.h>

int doubel_src_conbine(char *src, char *des);
int ptr_contain(char *src, char *des);

int main(){
	
	char src[] = "AABBCD";
	char des[] = "CDAA";
	if(ptr_contain(src, des))
		printf("src rotate contain des\n");
	else
		printf("scr donot contain des\n");
	return 0;
}

int ptr_contain(char *src, char *des){
	char *p = NULL;
	char *q = NULL;
	char *r = NULL;
	p = q = src;
	r = des;
	while(*p != '\0' && *p != *r)
		p++;
	if(*p == '\0')
		return 0;
	while(*(++r) != '\0'){
		if(*(++p) == '\0')
			p = q;
		if(*r != *p)
			return 0;
	}
	return 1;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值