您的位置:首页 > 职场人生

程序员编程艺术(算法卷):第一章、左旋转字符串

2012-03-29 16:10 537 查看
转载yu:http://blog.csdn.net/v_july_v/article/details/6322882

第一节、左旋转字符串

题目描述:


定义字符串的左旋转操作:把字符串前面的若干个字符移动到字符串的尾部。

如把字符串abcdef左旋转2位得到字符串cdefab。

请实现字符串左旋转的函数,要求对长度为n的字符串操作的时间复杂度为O(n),空间复杂度为O(1)

编程之美上有这样一个类似的问题,咱们先来看一下:

设计一个算法,把一个含有N个元素的数组循环右移K位,要求时间复杂度为O(N),

且只允许使用两个附加变量。

分析:

我们先试验简单的办法,可以每次将数组中的元素右移一位,循环K次。

abcd1234→4abcd123→34abcd12→234abcd1→1234abcd。

稍微总结下:

编程之美上,

下面,你将看到,本章里我们的做法是:

1、三次翻转,直接线性

2、两个指针逐步翻转,线性

3、stl的rotate算法,线性

好的,现在,回到咱们的左旋转字符串的问题中来,对于这个左旋转字符串的问题,咱们可以如下这样考虑:

1.1、思路一:

对于这个问题,咱们换一个角度可以这么做:

将一个字符串分成两部分,X和Y两个部分,在字符串上定义反转的操作X^T,即把X的所有字符反转(如,X="abc",那么X^T="cba"),那么我们可以得到下面的结论:(X^TY^T)^T=YX。显然我们这就可以转化为字符串的反转的问题了。

不是么?ok,就拿abcdef 这个例子来说(非常简短的三句,请细看,一看就懂):

1、首先分为俩部分,X:abc,Y:def;

2、X->X^T,abc->cba, Y->Y^T,def->fed。

3、(X^TY^T)^T=YX,cbafed->defabc,即整个翻转。
我想,这下,你应该了然了。

然后,代码可以这么写(已测试正确):

//Copyright@ 小桥流水 && July

//c代码实现,已测试正确。

//http://www.smallbridge.co.cc/2011/03/13/100%E9%A2%98

//_21-%E5%B7%A6%E6%97%8B%E8%BD%AC%E5%AD%97%E7%AC%A6%E4%B8%B2.html

//July、updated,2011.04.17。

#include <stdio.h>

#include <string.h>

char * invert(char *start, char *end)

{

char tmp, *ptmp = start;

while (start != NULL && end != NULL && start < end)

{

tmp = *start;

*start = *end;

*end = tmp;

start ++;

end --;

}

return ptmp;

}

char *left(char *s, int pos) //pos为要旋转的字符个数,或长度,下面主函数测试中,pos=3。

{

int len = strlen(s);

invert(s, s + (pos - 1)); //如上,X->X^T,即 abc->cba

invert(s + pos, s + (len - 1)); //如上,Y->Y^T,即 def->fed

invert(s, s + (len - 1)); //如上,整个翻转,(X^TY^T)^T=YX,即 cbafed->defabc。

return s;

}

int main()

{

char s[] = "abcdefghij";

puts(left(s, 3));

return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: