实现字符串的左旋:
注:有效次数为:总次数% N(如上图所示,假设对字符串左旋6次和左旋2次,得到的结果是一样的)
字符串左旋之—— 移首补尾法
思路:
- 左旋一次的方法: 将第一个字符存放起来,然后将第二个至最后一个字符依次向前挪一位,再将第一个字符放在末尾。
- 先写一个左旋一次的函数,然后需要左旋几次,就调用几次这个函数。
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<string.h>
#pragma warning(disable:4996)//屏蔽scanf出现的错误
char a[] = "abcd1234";//变量定义成全局较好
int len = strlen(a);
//移首补尾法:
void left_rotate_one(char* a, int len)
{
int tmp = a[0];
int i = 0;
while (i < len - 1)
{
a[i] = a[i + 1];
i++;
}
a[i] = tmp;
}
void left_rotate(char *a,int len,int count)
{
assert(a && count>0);
count %= len;
while (count--)
{
left_rotate_one(a, len);
}
}
int main()
{
int count = 0;
printf("please enter:\n");
scanf("%d", &count);
printf("%s\n", a);
left_rotate(a, len, count);
printf("%s\n", a);
system("pause");
return 0;
}
字符串左旋之——逆置法
思路:
- 如上图所示,假设左旋四次,先将字符数组分成两个区间。
- 前四个字符为一个区间,其后的字符占一个区间,将这两个区间的字符分别逆置。
- 然后再对这个字符数组整体逆置
//逆置法
void Swap(char *x,char *y)
{
int tmp = *x;
*x = *y;
*y=tmp;
}
void reverse( char*left, char* right)
{
while (left < right)
{
Swap(left, right);
left++;
right--;
}
}
void left_rotate(char a[], int len, int count)
{
assert(a&& len > 0 && count > 0);
reverse(a, a + count - 1);
reverse(a + count, a + len - 1);
reverse(a, a + len - 1);
}
左旋字符串之——双倍字符串
思路:
- 创建一个新数组,给它开原来字符数组的2倍的空间
- 将原来的字符数组里的内容拷贝进去,再将原来的字符串拼接至其尾部,此时原来的字符数组为空
- 对这个字符数组左旋n次,就是从新数组的a[n]位置读取,读取长度为len
// 双倍字符串法
void left_rotate(char a[], int len,int count)
{
assert(a && len > 0 && count > 0);
count %= len;
char *str = (char*)malloc(2*len+1);
if (!str)
{
return;
}
strcpy(str, a);
strcat(str, a);
strncpy(a, a + count, len);
}