题目:
判断一个字符串是否为另外一个字符串旋转之后的字符串。
例如:给定s1 =AABCD和s2 = BCDAA,返回1,给定s1=abcd和s2=ACBD,返回0.
AABCD左旋一个字符得到ABCDA
AABCD左旋两个字符得到BCDAA
AABCD右旋一个字符得到DAABC
思路:把源字符串追加到源字符串后边,这样问题就转化成了查找字串。可以利用strstr函数来完成,但是这里一定要注意还要进行长度的判断,因为旋转过后的字符串长度与原来字符串长度应该是相等的。
代码:
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<assert.h>
int Judge_str(char*str, char*substr)
{
assert(str);
assert(substr);
int ret;
int len_str = strlen(str);
int len_substr = strlen(substr);
char*tmp = malloc(sizeof(char)*(2 * len_str + 1));
if (tmp == NULL)
{
printf("申请空间失败 !\n");
exit(1);
}
strcpy(tmp, str);
strncat(tmp, str, len_str);
char*p = strstr(tmp, substr);//注意这里不能用tmp接收,因为如果查找到,则返回的是字串第一次出现的位置,而如果用tmp接收,则free(tmp)地址就变了,不是free掉原来开辟内存空间的起始地址处
if (p&&len_substr == len_str)//这里一定要检测空间有没有开辟成功
{
ret = 1;
}
else
{
ret = 0;
}
free(tmp);
return ret;
}
int main()
{
char str1[] = "AABCD";
char str2[] = "BCDAU";
int ret = Judge_str(str1, str2);
if (ret == 1)
{
printf("str2是str1旋转过后的串\n");
}
else
{
printf("str2不是str1旋转过后的串\n");
}
system("pause");
return 0;
}
思路二:
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<assert.h>
//左旋字符串
void Reverse(char*left, char*right)
{
while (left < right)
{
char tmp = *left;
*left = *right;
*right = tmp;
left++;
right--;
}
}
void Reverse_K(char*str, int k)
{
int len = strlen(str);
k %= len;//k有可能大于字符串的长度,但这也是合理的,相当于转了一圈,然后再移
Reverse(str, str + len - 1);//整体翻转
Reverse(str, str + len - 1 - k);//再翻转前半部分
Reverse(str + len - k, str + len - 1);//翻转后半部分
}
int IsLeftRotate(char*str1, char*str2)
{
int ret;
int len1 = strlen(str1);
int len2 = strlen(str2);
if (len1 != len2)
{
return 0;
}
while (len1)
{
Reverse_K(str1, 1);
if (strcmp(str1, str2) == 0)
{
return 1;
}
len1--;
}
return 0;
}
int main()
{
char str1[] = "ABCD";
char*str2 = "BCDA";
Reverse_K(str1, 3);
int ret = IsLeftRotate(str1, str2);
if (ret == 1)
{
printf("str2是str1旋转过后的串\n");
}
else
{
printf("str2不是str1旋转过后的串\n");
}
system("pause");
return 0;
}