实现一个函数,可以左旋字符串中的k个字符。
AABCD左旋一个字符得到ABCDA
AABCD左旋两个字符得到BCDAA
在C语言中,实现字符串旋转的方法有很多,今天我给大家介绍较为常见的三种实现方法,他们的时间复杂度还是有较大的差别,空间的占用也不尽相同,所以大家在以后的使用中按要求来选择实现的方法。
方法一:
利用指针的指向定位出每个字符,先实现每次向左循环移动一位,再通过循环控制移动的次数,最后返回指针即可。(优点:思路简单,缺点:效率不高)
具体实现:
方法二:利用局部逆置和整体逆置的结合来实现字符串的左移(优点:新开辟空间少,缺点:效率有待提高)例:将AABCD左移3位,先将AAB逆置为BAA,再将CD逆置为DC,
整体字符串变为BAADC,最后将整体逆置为CDAAB即为最后结果!
具体实现:
方法三:
利用穷举法来查找旋转后的字符串(优点:效率高,缺点:需要新开辟的内存空间较前两种方法大)
原理:利用新空间存入两个连续的相同的字符串,旋转后的所有可能将出现在该长字符串中,最后截取字符串获得最终字符串。
例:将AABCD左移3位,开辟新空间存入AABCDAABCD,直接从下标为3的地方截取长度为5的字符串即可。
具体实现:
该方法中需要注意的是strcpy()函数中的三个参数的作用 ,并且该函数本身不拷贝‘\0’,所以在第三个参数传长度时需要将‘\0’算进去。
AABCD左旋一个字符得到ABCDA
AABCD左旋两个字符得到BCDAA
在C语言中,实现字符串旋转的方法有很多,今天我给大家介绍较为常见的三种实现方法,他们的时间复杂度还是有较大的差别,空间的占用也不尽相同,所以大家在以后的使用中按要求来选择实现的方法。
方法一:
利用指针的指向定位出每个字符,先实现每次向左循环移动一位,再通过循环控制移动的次数,最后返回指针即可。(优点:思路简单,缺点:效率不高)
具体实现:
#include<stdio.h>
#include<assert.h>
#include<string.h>
void shiftStep(char *msg, int steps)
{
assert(msg); //判断指针合法
int len = strlen(msg);
steps %= len; //除以字符串长度取余数 提高效率
while (steps--) //步长减至0循环结束
{
char tmp = msg[0];
int i = 0;
for (i = 0; i < len - 1; i++)
{
msg[i] = msg[i + 1];
}
msg[i] = tmp;
}
}
int main()
{
char msg[] = "1234abcd";
int k=0;
printf("请输入左旋的位数:\n");
scanf("%d",&k);
shiftStep(msg, k);
printf("%s\n", msg);
return 0;
}
方法二:利用局部逆置和整体逆置的结合来实现字符串的左移(优点:新开辟空间少,缺点:效率有待提高)例:将AABCD左移3位,先将AAB逆置为BAA,再将CD逆置为DC,
整体字符串变为BAADC,最后将整体逆置为CDAAB即为最后结果!
具体实现:
#include<stdio.h>
#include<assert.h>
#include<string.h>
void swap(char *a, char *b) //将两个字符调换
{
assert(a);
assert(b);
*a ^= *b;
*b ^= *a;
*a ^= *b;
}
void reverseStr(char *start, char *end) //将字符串逆置
{
assert(start); //判断指针合法
assert(end);
while (start < end)
{
swap(start, end);
start++, end--;
}
}
void shiftStep(char *msg, int steps)
{
assert(msg);
int len = strlen(msg);
steps %= len;
reverseStr(msg, msg+steps-1); //将前半段字符串逆置
reverseStr(msg+steps, msg+len-1); //将后半段字符串逆置
reverseStr(msg, msg+len-1); //将字符串整体逆置
}
int main()
{
char msg[] = "1234abcd";
int k=0;
printf("请输入左旋的位数:\n");
scanf("%d",&k);
shiftStep(msg, k);
printf("%s\n", msg);
return 0;
}
方法三:
利用穷举法来查找旋转后的字符串(优点:效率高,缺点:需要新开辟的内存空间较前两种方法大)
原理:利用新空间存入两个连续的相同的字符串,旋转后的所有可能将出现在该长字符串中,最后截取字符串获得最终字符串。
例:将AABCD左移3位,开辟新空间存入AABCDAABCD,直接从下标为3的地方截取长度为5的字符串即可。
具体实现:
该方法中需要注意的是strcpy()函数中的三个参数的作用 ,并且该函数本身不拷贝‘\0’,所以在第三个参数传长度时需要将‘\0’算进去。
#include<stdio.h>
#include<assert.h>
#include<string.h>
void shiftStep(char *msg, int steps)
{
assert(msg); //判断指针合法
int len = strlen(msg);
steps %= len; //除以字符串长度取余数 提高效率
char *tmp = (char*)malloc(2*len+1); //开辟两个字符串长度的堆空间
strcpy(tmp, msg); //将目标字符串复制进新空间 1234abcd
strcat(tmp, msg); //将目标字符串拼接进新空间 1234abcd1234abcd
strncpy(msg, tmp+steps, len); //截取字符串放入msg中,第二个参数为起始截取位置,第三个参数为截取长度
free(tmp);
tmp = NULL;
}
int main()
{
char msg[] = "1234abcd";
int k=0;
printf("请输入左旋的位数:\n");
scanf("%d",&k);
shiftStep(msg, k);
printf("%s\n", msg);
return 0;
}