题目描述:字符串的左转操作:将字符串前面的若干个字符移动到字符串的尾部。
例如:把字符串abcdef 左旋转2位得到字符串cdefab。
要求:要求对字符串实现左旋转操作,并且对长度为n的字符串操作的时间复杂度为O(n),空间复杂度为O(1).
方法一、
我们可以讲字符串的左转想成如下过程:假设左转1个字符:
(1)、先把第一个字符提取出来;
(2)、后续的字符依次往前进一个;
(3)、完毕之后,把提取出来的第一个字符加到最后。
代码实现如下:
#include "LeftMoveChars.h"
void leftmovechars(char str[]);
int main()
{
char str[] = "abcdef";//此字符串长度为7,记得'\0'
printf("左转之前的字符串:%s\n",str);
leftmovechars(str);
printf("左转之后的字符串:%s\n",str);
getchar();
return 0;
}
void leftmovechars(char str[])
{
char ch = str[0];
for (int i = 1;i < 6;i++)
{
str[i-1] = str[i];
}
str[5] = ch;
return;
}
运行结果如下图:
完成了一个字符串的旋转之后,假如要完成前n个字符串,只需要对上述操作循环n次就行:
修改后的代码如下:
修改leftmovechars为如下方法:
void leftmovechars_by_n(char str[],int n)
{
for (int j = 0;j<n;j++)
{
char ch = str[0];
for (int i = 1;i < 6;i++)
{
str[i-1] = str[i];
}
str[5] = ch;
}
return;
}
在主函数调用:
int main()
{
char str[] = "abcdef";//此字符串长度为7,记得'\0'
printf("左转之前的字符串:%s\n",str);
//leftmovechars(str);
leftmovechars_by_n(str,3);
printf("左转之后的字符串:%s\n",str);
getchar();
return 0;
}
得到的运行结果如下:
如此我们就完成了字符串的左旋转。
但是该方法有个缺点,被移动的字符串都是一个个的被移动,由于考虑题目特点,被移动的字符串应当是整体的,可以被打包在一起整体移动的,所以我们可以采用下面的方法。
方法二、
主要思路如下:假设有7个长度的字符串abcdef‘\0’,左旋长度为3,那么将abc绑定在一起,依次往后移动
实现上可以设置两个指针p1、p2,分别指向第一个字符和第m个字符,这里的m是左旋长度
所以分别一一对应将两个数据交换,然后p1和p2分别向后移动。这里需要考虑两个问题,长度是否正好是旋转长度的整数倍,若不是,需要考虑p2指针移动长度不足的情况,此时只要把p2之后的数据和p1之后的数据有多少就交换多少就可以,而最后的'\0'不能被交换,否则系统会发生缺省读取'\0'之后的数据。
在最后不足长度的情况下做最后交换时,p1指针的最后一个数据优于无法和'\0'做交换,所以需要p1内部排序,将p1开始之后的数据全部赛到已交换的p1数据之后。
函数代码如下:
void leftmovechars_by_points(char str[],int n)
{
//首先获取字符串的长度
int length = 0;
while (*(str+length)!='\0')
{
length++;
}
printf("字符串长度为:%d\n",length);
//先定义两个指针,第一个指针指向第一个元素,第二个指针指向第n个元素;
char* p1 = &str[0];
char* p2 = &str[n];
char temp;
int mod = length % n;
int x = length / n;
if (0 == mod)
{
//从两个指针所指的位置开始两段长度为n的字符串的一一对应交换
while ( x-- != 1)
{
for(int i = 0;i<n;i++)
{
temp = *p1;
*p1 = *p2;
*p2 = temp;
p1++;
p2++;
}
}
}
else
{
//首先先交换x-1次
//从两个指针所指的位置开始两段长度为n的字符串的一一对应交换
while ( x-- != 1)
{
for(int i = 0;i<n;i++)
{
temp = *p1;
*p1 = *p2;
*p2 = temp;
p1++;
p2++;
}
}
while (*(p2)!='\0')
{
temp = *p1;
*p1 = *p2;
*p2 = temp;
p1++;
p2++;
}
if (*(p2) == '\0')
{
char* q = p1+1;
for (int k = 0;k < n-1 ;k++)
{
temp = *p1;
*p1 = *q;
*q = temp;
p1 = q;
q = q++;
}
}
}
return;
}
程序运行结果: