前言:
- 博主实力有限,博文有什么错误,望各位大佬,不吝赐教,非常感谢!
- 这是博主的专栏《剑指offer》第三篇,希望各位大佬多多支持,感谢!
题目:
实现一个函数,可以左旋字符串中的k个字符。
例如:
ABCD左旋一个字符得到BCDA
ABCD左旋两个字符得到CDAB
高效方法:三次辗转
思路:
注意
- 当左旋的次数超过字符串的长度时,会出现重复情况,因此对于 k%=k
代码:
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> #include <assert.h> void turn_arr(char* left, char* right) { assert(left && right);//用于防止传入空指针。 if (left > right)//防止传入左指针大于右指针 { return; } while (left< right)//将左右依次交换。 { char tmp = *left; *left = *right; *right = tmp; left++; right--; } } void left_arr(char* str, int k) { assert(str); int sz = strlen(str); k %= sz; turn_arr(str, str + k - 1);//反转左侧 ,注意字符数组的下标 turn_arr(str + k, str + sz - 1);//反转左侧 ,注意字符数组的下标 turn_arr(str, str + sz - 1);//反转整体 ,注意字符数组的下标 } int main () { char arr[] = "ABCDEF"; printf("%s\n", arr); int k = 0; scanf("%d", &k); left_arr(arr, k); printf("%s\n", arr); return 0; }
一般法
代码
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void left_spin1(char* p, int n)//递归方法
{
if (n)
{
int sz = strlen(p);
char tmp = p[0];
int i = 0;
for (i = 0; i < sz - 1; i++)
{
p[i] = p[i + 1];
}
p[sz - 1] = tmp;
left_spin1(p, n - 1);
}
else return;
}
void left_spin2(char* str, int n)//非递归方法
{
int sz = strlen(str);
int i = 0;
int j = 0;
for (i = 0; i < n; i++)
{
char tmp = str[0];//每次都保存字符串的第一个字符.
for (j = 0; j < sz - 1; j++)
{
str[j] = str[j + 1];
}
str[sz - 1] = tmp;
}
}
int main ()
{
char str1[] = "Hell World";
char str2[] = "Hell World";
int n = 0;
printf("请输入左旋的位数:");
scanf("%d", &n);
printf("递归方法 :");
left_spin1(str1, n);//递归方法
printf("%s\n", str1);
printf("非递归方法:");
left_spin2(str2, n);//非递归方法.
printf("%s\n", str2);
return 0;
}