我们先举个例子:
有一个字符串:“ABCDEF”。
要求做左旋两个字符得到:“CDEFAB”
一般情况下我们会写两个循环,一个负责字符交换,一个负责交换次数。也就是
第一次循环:A拿出来,BCDEF向前一步,把A放后面。
第二次循环:B拿出来,CDEFA向前一步,把B放后面。
今天我们不用暴力求解法,我们使用三步逆序法!
原理:根据需要旋转的个数将原字符分成两份,第一份做自我旋转,第二份也做自我旋转,然后将两个拼接起来再做一次旋转就得到了我们要的结果。
第一步:把要旋转的AB先单独旋转得到BA
第二步:把后面一部分CDEF旋转得到FEDC
第三步:把前两步得到BAFEDC旋转得到CDEFAB
接下来我们用指针来实现三步逆序法:
//用指针写的转换函数
void reverse(char* left, char* right)
{
//这里的left是字符串这一位的地址,right同理
while (left < right)
{
//*left是对地址的解引用也就是具体的值,right同理
char temp = *left;
*left = *right;
*right = temp;
//left++是地址加一,由于char是一个字节,所以加一就是加一个字节
//right同理
left++;
right--;
}
}
void left_reverse(char* arr, int n)
{
int len = strlen(arr);
//这种算法有个缺陷就是旋转的长度不能大于字符串长度
assert(n < len);//断言,报出故障点
reverse(arr, arr + n - 1);
reverse(arr + n, arr + len - 1);
reverse(arr, arr + len - 1);
}
//主函数
int main()
{
int n = 0;
printf("请输入字符串(0-999):>");
char arr[999] = {0};
gets(arr);
printf("请输入要旋转的次数:>");
scanf("%d", &n);
left_reverse(arr, n);
printf("旋转%d次后的结果为:>%s\n",n,arr);
return 0;
}
运行结果: