写一个函数,判断一个字符串是否为另外一个字符串旋转之后的字符串。
例如:给定s1 =AABCD和s2 = BCDAA,返回1;给定s1=abcd和s2=ACBD,返回0.
AABCD左旋一个字符得到ABCDA
AABCD左旋两个字符得到BCDAA
AABCD右旋一个字符得到DAABC
目录
法一:
思路:通过各下标,逐个逐个判断
假设字符串1,字符串2的下标分别i 和 j
第一步: 这里就将先寻找到字符串1与字符串2相同的元素,如果寻找K次(k是有效字符数)未找到则返回0;
如图
代码实现如下:
int time = size;
int i = 0, j = 0;
int door = 2;
// 让p1的i与p2的首元素对齐
while (time)
{
if (*(p1 + i) == *(p2 + 0)) // 找到对齐点退出
{
break;
}
i++;
time--;
}
if (time == 0) // 未找到相同元素
{
return 0;
}
第二步: 实现字符判断。
思路:如果 i 对应字符 同 j 对应字符相同,则 i++; 不同,则j++;如果连续出现2次不同则不是反转字符串,返回0。
代码实现如下:
// 开始判断
time = size + 1; // 省得创建新变量
while (time--)
{
// 取模
i %= size,j %= size; // 使超出下标回到限定范围
if (*(p1 + i) == *(p2 + j))
{
i++;
door = 2;
}
else if ( *(p1 + i) != *(p2 + j))
{
door--;
if (door == 0)
return 0;
j++;
}
}
return 1;
全部代码如下:
#include<stdio.h>
#include<string.h>
int check(char* p1, char* p2, int size)
{
int time = size;
int i = 0, j = 0;
int door = 2;
// 让p1的i与p2的首元素对齐
while (time)
{
if (*(p1 + i) == *(p2 + 0)) // 找到对齐点退出
{
break;
}
i++;
time--;
}
if (time == 0) // 未找到相同元素
{
return 0;
}
// 开始判断
time = size + 1; // 省得创建新变量
while (time--)
{
// 取模
i %= size,j %= size; // 使超出下标回到限定范围
if (*(p1 + i) == *(p2 + j))
{
i++;
door = 2;
}
else if ( *(p1 + i) != *(p2 + j))
{
door--;
if (door == 0)
return 0;
j++;
}
}
return 1;
}
int main()
{
char* a = "eabcd";
char* b = "deabc";
int size = strlen(a);
printf("%s\n", a);
printf("%s\n", b);
printf("%d ", check(a, b, size));
return 0;
}
法二(推荐):
思路:
其实ABCDE无论怎么旋,旋转后的所有结果,都包含在了ABCDEABCDE这个字符串里了。所以做法很简单,只需要将原字符串再来一遍接在后面,然后找一找待查找的字符串是不是两倍原字符串的子集即可。
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
int check_str(const char* a, const char* b)
{
char arr[128] = { 0 }; // 存放双倍字符串
strcpy(arr, a); // 拷贝一遍
strcat(arr, a); // 再拼接一份
return strstr(arr, b) != NULL; //不为空就是找到子链
}
int main()
{
char* a = "eabcd";
char* b = "deabc";
int size = strlen(a);
printf("%s\n", a);
printf("%s\n", b);
printf("%d ", check_str(a, b));
return 0;
}