旋转字符串是个经典问题。
要求:时间复杂度O(n),空间复杂度O(1)。
接口描述:http://www.sgi.com/tech/stl/rotate.html
《编程珠玑》、《编程之美》上都有这个问题,关于左旋右旋整个旋的方法我就不说了。
我的想法是,先左右比较,长的一段的大部分移到另一端,再递归进行余下的。
比如:
char str1[] = "abcdefghijklmnopqrstuvwxyz";
int mid = 3; // 从第mid个位置对调
size_t len = strlen(str1);
MyRotate(str1, str1 + mid, str1 + len);
执行过程:
abc defghijklmnopqrstuvwxyz
defghijklmnopqrstuvwx abcyz
defghijklmnopqrstuvwx ayz bc
defghijklmnopqrstuvwx yz a bc
程序如下,非递归的版本还没想好。
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
char * g_head = NULL; // 为了debug
void MyRotate(char *const first, char *const middle, char *const last)
{
cout << g_head << endl;
int leftLen = middle - first;
int rightLen = last - middle;
if (leftLen == 0 || rightLen == 0)
{
return ;
}
if (leftLen <= rightLen)
{
char *dst = first;
char *src = middle;
int count = rightLen / leftLen * leftLen;
for (int i = 0; i < count; ++i)
{
char tmp = *dst;
*dst = *src;
*src = tmp;
++dst;
++src;
}
MyRotate(dst, src, last);
} else {
char *src = middle - 1;
char *dst = last - 1;
int count = leftLen / rightLen * rightLen;
for (int i = 0; i < count; ++i)
{
char tmp = *dst;
*dst = *src;
*src = tmp;
--dst;
--src;
}
MyRotate(first, src + 1, dst + 1);
}
}
int main(int argc, char **argv)
{
char str1[] = "abcdefghijklmnopqrstuvwxyz";
int mid = 3; // 从第mid个位置对调
char str2[100];
strcpy(str2, str1);
g_head = str1;
size_t len = strlen(str1);
MyRotate(str1, str1 + mid, str1 + len);
rotate(str2, str2 + mid, str2 + len);
cout << (strcmp(str1, str2) == 0 ? "right" : "wrong") << endl;
return 0;
}
STL是最强大的,算法源码详见
http://www.sgi.com/tech/stl/stl_algo.h,你可以Ctrl+F找下rotate,再看看它的代码。
网上还找到了这个http://opensource.apple.com/source/gcc/gcc-1640/libstdc++-v3/include/bits/stl_algo.h
STL的源码看懂了再更新到这里。