左旋字符

问题描述:

 实现一个函数,可以左旋字符串中的k个字符。
AABCD左旋一个字符得到ABCDA
AABCD左旋两个字符得到BCDAA

该问题有三种方法,现做一一分析

法一:通过移动字符实现左旋

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<windows.h>

char *leftstring(char *str, int num,int len)
{
	char arr[10];
	char *p = str,*q = str;
	int i = 0;
	for (i = 0; i < num; i++)         //比如我们需要左旋两个字符串,那么先把原字符串的最前面的两个字符存起来
	{
		arr[i] = *p++;
	}
	p = str;
	p += num;                         //用p指向需要前移的第一个字符
	for (i = num; i < len-1; i++)   //从第一个字符开始依次把后面的字符前移,做前移操作,i控制次数
	{
		*str++ = *p++;
	}
	for (i = 0; i < num; i++)       //把刚刚取出来的字符,存到原字符串前移后的后面
	{
		*str++ = arr[i];
	}
	return q;
}

int main()
{
	char arr[] = "AABCD";
	int len = sizeof(arr) / sizeof(arr[0]);
	leftstring(arr, 2, len);
	printf("%s\n",arr);
	system("pause");
	return 0;
}

法二:通过置换函数进行左旋操作

比如abcd1234,如果我们想左旋四个,我们可以先把前面四个逆序得到dcba,接着把后面逆序得到4321,这样两次逆序后的结果是dcba4321,然后再整体逆序,得到了1234abcd,同样的方法大家可以试一下左旋两个是不是同样的效果

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<assert.h>
#include<windows.h>

//通过置换函数进行左旋操作

void swap(char *p, char *q)     //置换两个字符
{
	assert(p);             //每次传入一个地址时进行断言,防止传址出错
	assert(q);
	*p ^= *q;
	*q ^= *p;
	*p ^= *q;
}

char *ReverseOrder(char *left, char *right)   //置换一组字符
{
	assert(left);
	assert(right);
	char *arr = left;
	while (arr < right)
	{
		swap(arr, right);
		arr++, right--;
	}
	return left;
}

char *leftstring(char *str, int num,int len)   //通过前后字符替换实现左旋
{
	assert(str);
	char *string = str;                       
	num = num % len;                          //加上一个取余的操作,目的是如果左旋的次数大于字符串的长度,比如该题如果是9,实际的结果只左旋了一次
	ReverseOrder(string, string + num - 1);          //先置换前一部分,再置换后一部分,然后整体置换
	ReverseOrder(string + num, string + len - 1);
	ReverseOrder(string, string + len - 1);
	
	return str;
}

int main()
{
	char arr[] = "abcd1234";
	int len = (sizeof(arr) / sizeof(arr[0])) - 1;
	leftstring(arr, 2, len);
	printf("%s\n",arr);
	system("pause");
	return 0;
}

法三:通过在拼接进行左旋,把和原字符串同样内容的字符串拼接在原字符串的后面

分析如下,如果我们的原字符串是abcd1234,现在我左旋2,想要得到的结果是cd1234ab,我使用本方法是在原字符串的后面拼接一整个,得到abcd1234abcd1234,然后从第三个字符开始把内容依次复制到原字符串中去,循环的次数是8.

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<assert.h>
#include<windows.h>
#include<string.h>

//通过在拼接进行左旋,把和原字符串同样内容的字符串拼接在原字符串的后面

char *leftstring(char *str, int num, int len)
{
	assert(str);
	int i = 0;
	char *string = str;
	char *arr = (char *)malloc(2*len + 1);    //开辟空间使2*len+1,其中+1位为了给结尾处留有一个'\0'的空间
	num = num % len;
	strcpy(arr,string);
	strcat(arr,string);
	for (i = 0; i < len; i++)
	{
		*string++ = arr[i+num];
	}
	return str;
}

int main()
{
	char arr[] = "abcd1234";
	int len = (sizeof(arr) / sizeof(arr[0])) - 1;
	leftstring(arr, 2, len);
	printf("%s\n",arr);
	system("pause");
	return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值