目录
第一题:实现一个函数可以左旋字符串中k个字符
思路1:移位
我们可以将第一个字符存起来,其余字符依次向前移动一位,最后将第一个字符放到最后一位,依次循环
图解
伪代码
由于每次循环指针加一都会循环到\0处停止,所以我们需要一个另外一个指针来指向该指针,这样该指针就永远指向的是第一个元素,这样就可以无限交换
● 通过while循环来控制交换的次数
●用一个新指针代替旧指针,并将首元素存在另外一个空间里
●从“第一个”元素依次向前移动一位*pp=*(pp+1)
●判断*(pp+1)是否指向'\0', '\0'不能向前移
●新指针向后移动
●将新元素放到最后,也就是*pp的位置
代码1
#include<stdio.h>
void left_swap(char* p, int n) {
while (n--) {
char*pp = p;//用新指针代替旧指针
char temp = *pp;//将第一个元素存起来,最后放到最后面
while (*(pp + 1) != '\0') {//元素依次前移
*pp = *(pp + 1);
pp++;
}
*pp = temp;
}
}
int main() {
char arr[] = "ABCDE";
printf("请输入要旋转字符的数量:");
int n;
scanf("%d", &n);
left_swap(arr, n);
printf("%s", arr);
}
代码2
这个不需要移动指针,但是用了strlen()这个函数,总体来说这个算法好,没那么麻烦
#include<stdio.h>
#include<string.h>
void left_swap(char* p, int n) {
//while (n--) {
// char*pp = p;//用新指针代替旧指针
// char temp = *pp;//将第一个元素存起来,最后放到最后面
// while (*(pp + 1) != '\0') {//元素依次前移
// *pp = *(pp + 1);
// pp++;
// }
// *pp = temp;
//}
for(int i=0;i<n;i++){
char temp = *p;//将第一个元素存起来
for (int j = 0; j < strlen(p) - 1; j++) {//其余元素前移
*(p + j) = *(p + j + 1);
}
*(p + strlen(p) - 1) = temp;//将第一个元素放入最后的位置
}
}
int main() {
char arr[] = "ABCDE";
printf("请输入要旋转字符的数量:");
int n;
scanf("%d", &n);
left_swap(arr, n);
printf("%s", arr);
}
思路二:三步翻转
我们首先翻转要旋转的字符,然后在翻转不旋转的字符,最后将全部字符翻转
图解
伪代码
●我们需要翻转和不翻转子字符串的具体范围
●通过另外一个函数实现子字符串的逆序
代码
#include<stdio.h>
#include<string.h>
void swap(char*l, char*r) {
while (l < r) {//至少两个元素才交换
int temp = *l;
*l = *r;
*r = temp;
l++;
r--;
}
}
void left_swap(char* p, int n) {
swap(p, p + n - 1);//每个子字符串的范围
swap(p + n, p + strlen(p) - 1);
swap(p, p+strlen(p) - 1);//0+5-1=4是第五个元素
}
int main() {
char arr[] = "ABCDE";
printf("请输入要旋转字符的数量:");
int n;
scanf("%d", &n);
left_swap(arr, n);
printf("%s", arr);
}
题目二:字符串旋转结果
思路
在第一个题目的思路上,只需比较每次左旋时候两个数组的内容即可这里需要用到strcmp()
伪代码
●对其中任意一个数组进行遍历左旋
●遍历的次数为数组的长度,因为第一次遍历的时候把第一个元素放到了后面,第strlen(arr)次有回到了刚开始的状况
●遍历每次数组左旋的结果与目标数组进行比较
代码
#include<stdio.h>
#include<string.h>
void swap(char*l, char*r) {
while (l < r) {//至少两个元素才交换
int temp = *l;
*l = *r;
*r = temp;
l++;
r--;
}
}
void left_swap(char* p, int n) {
swap(p, p + n - 1);//每个子字符串的范围
swap(p + n, p + strlen(p) - 1);
swap(p, p+strlen(p) - 1);//0+5-1=4是第五个元素
}
//判断arr是否是arr2旋转后的结果
int is_left_swap(int *arr, int *arr2) {
int len = strlen(arr);
for (int i = 0; i < len; i++) {//遍历每次左旋的结果
left_swap(arr, 1);
if (strcmp(arr, arr2) == 0) {//每次遍历判断是否与目标数组相等
return 1;
}
}
return 0;//若不相等则返回0
}
int main() {
char arr[] = "ABCDE";
char arr2[] = "CDEAB";
int num=is_left_swap(arr,arr2);
if (num) {
printf("YES\n");
}
else {
printf("NO\n");
}
}
还有一种解法过几天再写