写一个函数,判断一个字符串是否为另外一个字符串旋转之后的字符串。
例如:给定s1 =AABCD和s2 = BCDAA,返回1
给定s1=abcd和s2=ACBD,返回0.
AABCD左旋一个字符得到ABCDA
AABCD左旋两个字符得到BCDAA
AABCD右旋一个字符得到DAABC
@TOC
一、方法一(暴力求解法)
代码实现
#include<stdio.h>
#include<assert.h>
void left_move(char* arr, int len, int n)
{
assert(arr && len > 0 && n >= 0);
n = n % len;//为了避免n大于字符串长度,浪费时间
while (n)
{
char ret = arr[0];
int i = 0;
for (i = 0; i < len-1; i++)
{
arr[i] = arr[i + 1];
}
arr[i] = ret;
n--;
}
}
int main()
{
char arr1[] = "woyaojindachang";
char arr2[] = "jindachangwoyao";
int len = strlen(arr1);
int i = 0;
for ( i = 0; i < len; i++)
{
if (strcmp(arr1, arr2) == 0)
{
printf("yes\n");
break;
}
left_move(arr1, len, 1);
}
if (i == len)
{
printf("no");
}
return 0;
}
二、方法二(三步翻转法)
1.思路
将代码分为2部分:1.要旋转的部分 2.不旋转的部分
三步翻转分别为:1.将要旋转的旋转 2.将不旋转的旋转 3.整体旋转
例如
ABCD 要旋转两个字符--> AB CD
1.先将旋转部分ab逆序-->BA CD
2.再将不旋转部分逆序-->BA DC
3.最后全部逆序-->CDAB
2.代码实现
void move(char* arr, int start, int end)
{
while (start < end)
{
char t = arr[start];
arr[start] = arr[end];
arr[end] = t;
start++;
end--;
}
}
void left_move(char* arr, int len, int n)
{
assert(arr && len > 0 && n >= 0);
n = n % len;
move(arr, 0, n - 1);
move(arr, n, len - 1);
move(arr, 0, len - 1);
}
int main()
{
char arr1[] = "woyaojindachang";
char arr2[] = "jindachangwoyao";
int len = strlen(arr1);
int i = 0;
for (i = 0; i < len; i++)
{
if (strcmp(arr1, arr2) == 0)
{
printf("yes\n");
break;
}
left_move(arr1, len, 1);
}
if (i == len)
{
printf("no");
}
return 0;
}
三、方法三(字串判断法)
1.思路
将一旋转字符串自身连接,然后判断另一个字符串是否为连接后的字符串的子串,如果是,则是旋转后的字符串,否则,相反。
2.代码实现
int is_left_move(char* arr1, char* arr2)
{
int len1 = strlen(arr1);
int len2 = strlen(arr2);
if (len1 != len2)
{
return 0;
}
strncat(arr1, arr1, len1);
//追加自身字符串必须使用strncat,strcat适用不同字符串连接
char* ret = strstr(arr1, arr2);
//判断arr1里有没有子串arr2
if (ret == NULL)
return 0;
else
return 1;
}
int main()
{
char arr[20] = "AABCD";
char arr1[] = "ABCDA";
int n = is_left_move(arr, arr1);
if (n)
{
printf("YES\n");
}
else
{
printf("NO\n");
}
return 0;
}