实现一个函数,可以左旋字符串中的k个字符

实现一个函数,可以左旋字符串中的k个字符。
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;
} 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值