字符串左旋
本期介绍🍖
主要介绍:字符串左旋,以及判断是否为旋转后的字符串。
文章目录
- 1. 字符串左旋
- 1.1 按次旋一法
- 1.2 strncat库函数法
- 1.3 三步翻转法
- 2. 判断是否是旋转后的字符串
- 2.1 旋一判断法
- 2.2 strstr库函数法
1. 字符串左旋
题目: 实现一个函数,能够左旋字符串中的k个字符。举个例子:对于字符串“abcdef”左旋1个字符结果为“bcdefa”,若左旋3个字符结果为“defabc”。
1.1 按次旋一法
解题思路:每次将字符串向左旋一个字符。先将字符串首字符保存起来,然后将后面剩余的字符全部往前挪一位,最后将保存的首字符覆盖掉最后一位字符,左旋n个字符就只要执行n次就可以了。如下图所示:
实现代码如下:
#include<stdio.h>
#include<string.h>
void left_move(char str[], int k)
{//排除周期旋转次数int len = strlen(str);int mov = k % len;//开始左旋int i = 0;for (i = 0; i < mov; i++){//1.保存首字符char tmp = str[0];//2.剩余字符往前挪一位int j = 0;for (j = 0; j < len - 1; j++){str[j] = str[j + 1];}//3.将保存的字符放到末尾str[len - 1] = tmp;}
}
int main()
{char str[] = "abcdef";int k = 0;scanf("%d", &k);left_move(str, k);printf("%s\n", str);return 0;
}
1.2 strncat库函数法
解题思路:通过调用C语言string.h
库函数中的strcpy()
和strncat()
函数,实现字符串的左旋。首先需要介绍一下这两个库函数,如下所示:
strcpy(str1, str2)
字符串拷贝函数,将str2的内容拷贝到str1中,若str1中原本就存在字符串会被覆盖掉。
strncat(str1, str2, n)
字符串连接函数,若str1中原本就存在字符串,会将str2连接到该字符串后面,连接的数量由n决定。
实现代码如下:
#include<stdio.h>
#include<string.h>
void left_move(char str[], int k)
{//排除周期旋转次数int len = strlen(str);int mov = k % len;//开始左旋char arr[256] = { 0 };strcpy(arr, str + mov);strncat(arr, str, mov);strcpy(str, arr);
}
int main()
{char str[] = "abcdef";int k = 0;scanf("%d", &k);left_move(str, k);printf("%s\n", str);return 0;
}
1.3 三步翻转法
翻转法的用处就是能将字符串拆分的各个部分,从原来的顺序排放变成逆序排放。假设我要将字符串“abcdef”左旋2次,可以先将它拆分成“ab”和“cdef”两个部分,然后分别对其进行逆序操作得到“bafedc”,最后将整个字符串逆序就能得到左旋2个字符后的字符串“cdefab”,这就是翻转法。如下图所示:
实现代码如下:
#include<stdio.h>
//逆置字符串
void reverse(char* head, char* end)
{while (head < end){char tmp = *head;*head = *end;*end = tmp;head++;end--;}
}
void left_move(char str[], int k)
{//排除周期旋转次数int len = strlen(str);int mov = k % len;//开始左旋reverse(str, str + mov - 1);reverse(str + mov, str + len - 1);reverse(str, str + len - 1);
}
int main()
{char str[] = "abcdef";int k = 0;scanf("%d", &k);left_move(str, k);printf("%s\n", str);return 0;
}
2. 判断是否是旋转后的字符串
题目: 实现一个函数,判断一个字符串是否为另外一个字符串旋转之后的字符串。例如:给定s1 =AABCD和s2 = BCDAA,返回1。给定s1=abcd和s2=ACBD,返回0。
2.1 旋一判断法
我们可以通过字符串每一次左旋得到的结果来与之比较,只要其中有一次能得到两字符串相等,那么就代表可以由另一个字符串旋转的来,反之则不能由另一个字符串得来。代码如下:
#include<stdio.h>
#include<string.h>
int is_left_move(char str1[], char str2[])
{int len1 = strlen(str1);int len2 = strlen(str2);if (len1 != len2)return 0;//左旋str1与str2进行比较char arr[256] = { 0 };strcpy(arr, str1);int i = 0;for (i = 0; i < len1 - 1; i++){if (strcmp(arr, str2) == 0)return 1;//左旋一位char tmp = arr[0];int j = 0;for (j = 0; j < len1 - 1; j++){arr[j] = arr[j + 1];}arr[len1 - 1] = tmp;}return 0;
}
int main()
{char str1[] = "abcdef";char str2[] = "bcdefa";int flag = is_left_move(str1, str2);if (flag == 1)printf("%s可以通过%s旋转得来\n", str1, str2);
elseprintf("%s不可以通过%s旋转得来\n", str1, str2);return 0;
}
2.2 strstr库函数法
解题思路:在一个字符串后面追加一个自己,这样关于字符串的所有的旋转的情况都存在于这个追加后的字符串中。举个例子:字符串“abcdef”追加后“abcdefabcdef”
,那么“bcdefa”
、“cdefab”
、“defabc”
……都是字符串“abcdefabcdef”
的子字符串,都是字符串“abcdef”旋转之后的情况。所以想要判断一个字符串是否由另一个字符串旋转得来,只需要判断是否为追加后字符串的子字符串就可以了。
下面介绍一个库函数strstr(str1, str2)
,用于在str1字符串中查找是否存在str2字符串。若找到了则返回str2在str1中的地址,若没找到则返回NULL。
#include<stdio.h>
#include<string.h>
int is_left_move(char str1[], char str2[])
{int len1 = strlen(str1);int len2 = strlen(str2);if (len1 != len2)return 0;//字符串追加char arr[256] = { 0 };strcpy(arr, str1);strcat(arr, str1);//字符串查找if (strstr(arr, str2) != NULL)return 1;elsereturn 0;
}
int main()
{char str1[] = "abcdef";char str2[] = "bcdefa";int flag = is_left_move(str1, str2);if (flag == 1)printf("%s可以通过%s旋转得来\n", str1, str2);elseprintf("%s不可以通过%s旋转得来\n", str1, str2);return 0;
}
这份博客👍如果对你有帮助,给博主一个免费的点赞以示鼓励欢迎各位🔎点赞👍评论收藏⭐️,谢谢!!!
如果有什么疑问或不同的见解,欢迎评论区留言欧👀。