题目:实现一个函数,可以左旋字符串中的k个字符。
例如:
ABCD左旋一个字符得到BCDA
ABCD左旋两个字符得到CDAB
解法1:设计循环可以旋1次,然后让他执行n次是一个最简单的思路:
代码如下:
void leftRound1(char* str, int time)
{
int i, j, tmp;
int len = strlen(str);
time %= len; //长度为5的情况下,旋转6、11、16...次相当于1次,7、12、17...次相当于2次,以此类推。
for (i = 0; i < time; i++) //执行k次的单次平移
{
tmp = str[0];
for (j = 0; j < len - 1; j++) //单次平移
{
str[j] = str[j + 1];
}
str[j] = tmp;
}
}
运行图:
解法2:拼接法
这里需要用到用到strcpy和strncat两个函数。下面简单介绍一下:
strcpy 函数
strcpy 是 “string copy” 的缩写,用于将一个字符串复制到另一个字符串。其原型在 <string.h> 头文件中定义:char *strcpy(char *dest, const char *src); //dest: 指向目标字符数组的指针,该数组必须足够大,以便能够存放源字符串的副本以及结尾的空字符 '\0'。 //src: 指向要复制的源字符串的指针。 //返回值: 函数返回一个指向目标字符串 dest 的指针。 //注意:使用 strcpy 时要确保目标数组 dest 有足够的空间来存储源字符串 src,否则可能会导致缓冲区溢出。
strncat 函数
strncat 是 “string concatenate” 的缩写,用于将两个字符串连接起来,但是它只从源字符串中复制指定数量的字符。其原型也在 <string.h> 头文件中定义:char* strncat(char* dest, const char* src, size_t n); //dest: 指向目标字符数组的指针,该数组应该已经包含一个字符串,并且有足够的空间来添加源字符串的副本。 //src: 指向要连接的源字符串的指针。 //n: 要从源字符串复制的最大字符数。 //返回值: 函数返回一个指向目标字符串 dest 的指针。 //注意:strncat 函数不会在目标字符串 dest 后面自动添加空字符 '\0',它假设 dest 已经以空字符结尾。如果 n 大于 src 字符串的长度,则只复制到 src 的结尾空字符。
了解了用法,接下来我们使用:
void leftRound2(char* str, int time)
{
int len = strlen(str);
int pos = time % len; //断开位置的下标
char tmp[256] = { 0 }; //更准确的话可以选择malloc len + 1个字节的空间来做这个tmp
strcpy(tmp, str + pos); //先将后面的全部拷过来
strncat(tmp, str, pos); //然后将前面几个接上
strcpy(str, tmp); //最后拷回去
}
运行图:
解法3 :类似循环队列思想
void leftRound3(char* str,int k)
{
int len = strlen(str);
int i = k%len;
int j = 1;
while(j<=len)//j用来计数看是否到达len次
{
printf("%c", str[i]);//先找出旋转后第一个需要打印的字符,再循环
i++;
if (j == len - k%len)
i = 0;
j++;//打印长度和用来字符串一样长就行
}
}
运行图: