字符串左旋,简单思路+改进思路!!!

目录

先看代码,下面有解析奥!!有两个改进思路也在下面!!

解题思路

代码解析

1.主函数

2.左旋函数

改进思路

改进一:

改进二:


先看代码,下面有解析奥!!有两个改进思路也在下面!!

void leftro(char* arr,int a)
{

	while (a)
	{
		char* brr = arr;
		char tmp = *brr;
		while (*(brr + 1) != '\0')
		{
			*brr = *(brr + 1);
			brr ++;
		}
		*brr = tmp;
		a--;
	}
}
int main()
{
	char arr[] = "ABCD";
	int a = 0;
	scanf("%d", &a);
	leftro(arr, sz,a);
	printf("%s", arr);
	
	return 0;
}

解题思路

一个字符串ABCD,左旋一次后变成BCDA,两次则为CDAB,即将最前面的字符移到最后面即可。

代码解析

1.主函数

在主函数中,先定义字符串,并且输入一个数字a作为旋转的次数,最终将左旋字符串函数打印出即可

int main()
{
	char arr[] = "ABCD";
	int sz = sizeof(arr) / sizeof(arr[0]);
	int a = 0;
	scanf("%d", &a);
	leftro(arr, sz,a);
	printf("%s", arr);
	
	return 0;
}

2.左旋函数

在左旋函数中,首先先定义一个字符指针来接收arr字符数组,即接收字符串ABCD。

1.  用while循环进行循环左旋,以a作为表达式,就是在左旋每进行完一次,就让a--直到a = 0,为了避免arr被更改首先定义一个brr接收arr指针,然后用一个变量tmp接收 *brr(解引用brr),得到ABCD中第一个字符A

2.  内循环中表达式的意思是,让字符串从A进行字符串交换,直到A移到D的位置,并且   (*(brr+1))(意思是下一个字符)是\0 时停止。每次循环brr++,即让brr在数组中的地址+1,。最后再将tmp的值传到目前brr的地址中即可。因为当A走到D区域时就会停止,因为D区域下一个字符就是\0 ,所以将brr现在位置的值改为tmp,实则是为了将D改为A

void leftro(char* arr,int a)
{

	while (a)
	{
		char* brr = arr;
		char tmp = *brr;
		while (*(brr + 1) != '\0')
		{
			*brr = *(brr + 1);
			brr ++;
		}
		*brr = tmp;
		a--;
	}
}

改进思路

改进一:

这个思路当然可以,但是一次一次转毕竟太麻烦,就不能一次到位么?

当然可以,我们可以选择拼接法,一次到位:

void leftRound(char * src, int time)
{
	int len = strlen(src);
	int pos = time % len; //断开位置的下标
	char tmp[256] = { 0 }; //更准确的话可以选择malloc len + 1个字节的空间来做这个tmp
	
	strcpy(tmp, src + pos); //先将后面的全部拷过来
	strncat(tmp, src, pos); //然后将前面几个接上
	strcpy(src, tmp); //最后拷回去
}

改进思路主要就是要知道下面几个库函数的用法即可。

改进二:

这个方法要用到一个数组形成的辅助空间,让人觉得有点不爽,还可以有更好的选择,例如ABCDEFG,左旋3次后变成DEFGABC,有一个特殊的操作方式:

先将要左旋的前三个家伙逆序(CBADEFG),然后将后半段也逆序(CBAGFED),最后整体逆序(DEFGABC)即可。这样只需要做数值交换即可,可以写一个函数帮我们完成局部逆序,代码如下:

void reverse_part(char *str, int start, int end) //将字符串从start到end这一段逆序
{
	int i, j;
	char tmp;

	for (i = start, j = end; i < j; i++, j--)
	{
		tmp = str[i];
		str[i] = str[j];
		str[j] = tmp;
	}
}

void leftRound(char * src, int time)
{
	int len = strlen(src);
	int pos = time % len;
	reverse_part(src, 0, pos - 1); //逆序前段
	reverse_part(src, pos, len - 1); //逆序后段
	reverse_part(src, 0, len - 1); //整体逆序
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值