字符串左旋

题目内容

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

例如:
        ABCD左旋一个字符得到BCDA

        ABCD左旋两个字符得到CDAB

方法一:逐个字符左旋

解题思路:

将字符串中第一个字符保存下来,然后将之后的字符一个一个向前位移,在最后添加保存下来的第一个字符,以此循环。 

 首先,我们需要根据字符串的左旋次数(time)来确定左旋的次数(count)。无论字符串有多长,只要当左旋次数到达一定值时,字符串便会变回原本的序列。

由图可知,当字符串长度为4时,左旋次数达到4次时字符串变回了原本的序列,由此可得,字符串的左旋有效变化次数为time = time % len 。

接着,我们需要嵌套循环来完成每一次左旋变化中字符串内部字符的左移。

我们需要在对应下标位置赋值上下一个下标位置的值:

arr[j] = arr[j+1]

完成一个位置的数据交换后我们也同样需要对下一个位置进行操作,由此可知,j 是本次循环的变量,同时 j 的变化也影响着循环进程。

将 j 的值作为循环结束的条件,我们需要分析 j 需要在什么位置停止后移。由赋值代码分析可得,在循环中我们需要对每一个有效数据进行赋值,直到 j+1 超出边界。所以 j 将停留在倒数第二个有效数据,也就是len-1。

 当 j 不满足条件退出循环时,我们需要在字符串结尾赋值保存下来的第一个字符,这样一次循环就完成了。

代码展示

以字符串"abcd"为例左旋3次

void leftround(char arr[], int key)
{
	int len = strlen(arr);
	int count = 0;
	int j = 0;
	key = key % len;

	for (count = 0; count < key; count++)//左旋次数
	{
		char tmp = arr[0];
		for (j = 0; j < len - 1; j++)
		{
			arr[j] = arr[j + 1];
		}
		arr[j] = tmp;//将保存好的第一个字符放在最后
	}
}
int main()
{
	char arr[100] = "abcd";
	leftround(arr, 3);
	printf("%s\n",arr);
	return 0;
}

 运行结果:

方法二: 拷贝+拼接

解题思路:

我们可以利用库函数strcpy和strncat,通过对指定位置拷贝和拼接来完成字符串左旋。

对于如何找到指定位置进行拷贝和拼接,我们需要使用 数组名+左旋次数 来完成对指定位置的拷贝。

代码展示

以字符串"abcdef"为例左旋4次

void leftround(char arr[], int time)
{
	int len = strlen(arr);
	time = time % len;
	char tmp[100] = { 0 };

	strcpy(tmp, arr + time);//往tmp中拷贝ef
	strncat(tmp, arr, time);//在tmp中拼接arr中的前time个字符abcd
	strcpy(arr, tmp);//将tmp中的字符串拷贝到arr中
}
int main()
{
	char arr[100] = "abcdef";
	leftround(arr, 4);
	printf("%s\n", arr);
	return 0;
}

运行结果:

方法三:利用数组下标进行逆置

解题思路:

将左旋次数前time个字符进行逆置,同时将之后的字符进行逆置,最后整体逆置。

本次左旋我们只用到了逆置的操作,所以我们可以单独设计一个逆置的函数来完成本次左旋。

我们可以以传递数组下标的方式确定每一次逆置的范围,而后对字符串中的字符进行左右交换。

void reverse(char arr[], int left, int right)
{
	while (left < right)
	{
		char tmp = arr[left];
		arr[left] = arr[right];
		arr[right] = tmp;

		left++;
		right--;
	}
}

对于下标的确定方式,我们需要使用字符串长度len和左旋次数time进行调整。

代码展示

以字符串"abcdef"为例左旋4次

void reverse(char arr[], int left, int right)//逆置函数
{
	while (left < right)
	{
		char tmp = arr[left];
		arr[left] = arr[right];
		arr[right] = tmp;

		left++;
		right--;
	}
}
void leftround(char arr[], int time)
{
	int len = strlen(arr);
	time %= len;

	reverse(arr, 0, time - 1);//找到前time个字符进行逆置
	reverse(arr, time, len - 1);//对之后的字符进行逆置
	reverse(arr, 0, len - 1);//整体逆置
}
int main()
{
	char arr[100] = "abcdef";
	leftround(arr, 4);
	printf("%s\n", arr);
	return 0;
}

运行结果:

总结 

完成字符串左旋的方法有很多种,可以对其逐个左旋,也可以利用库函数快速解决。通过发掘不同的解题思路去解决问题,有助于我们逻辑思维能力的提升。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值