左旋字符串

在网上一位博主的博客中看了有关左旋字符串的算法,原文地址http://blog.csdn.net/v_july_v/article/details/6322882,此博文给出了很多种解法,在这里我提出一些自己的观点。

题目描述:

定义字符串的左旋转操作:把字符串前面的若干个字符移动到字符串的尾部。
如把字符串abcdef左旋转2位得到字符串cdefab。
请实现字符串左旋转的函数,要求对长度为n的字符串操作的时间复杂度为O(n),空间复杂度为O(1)

大家都知道,现在用算法用的最多的地方就是ACM了,现在假如我们把这道题看成一道ACM的算法题,那么题目就变得很简单了。因为OJ对结果的判断只是进行字符串的匹配工作,假如题目的输入是abcdef,你最后只要输出cdefab就算你对了,你代码的执行过程发生了什么事就无所谓了。如果真的是这样的话,那这道题就很简单了。

我们只要用一个指针,开始定位到要旋转的位置的下一位,即上述字符串abcdef的c,然后做输出,最后把字符c改为'\0',输出整个字符串就行了(其实就是输出了旋转到后面的那部分),代码如下

#include <stdio.h>
int main()
{
	char str[100];
	int rotate = 0;
	while(scanf("%s",str))
	{
		scanf("%d",&rotate);
		char *p = str + rotate;
		printf("%s",p);
		*p = '\0';
		printf("%s\n",str);
	}
	return 0;
}

如果是右旋转,就把p从后面算回就可以了。

好了,现在我们不把它看成一个ACM的题目,如果题目的要求是改变字符串的内容,即把abcdef改成cdefab,我提出自己的观点,因为我在大三的时候做数据结构课程的作业就是这样做的。空间复杂度是O(1),时间复杂度为O(N)。

算法的基本思路是,把要旋转的字符串分成n组(n为左旋的位数),例如源字符串为abcdef,向左旋转2位,得到cdefab

a b c d e f

分成以下两组,然后分别对这两组进行循环移位就行了

a   c   e  
  b   d   f

变成以下两组:

c   e   a  
  d   f   b

合起来之后,就变成了旋转之后的字符串

c d e f a b

根据思路得到以下代码:

void Rotate(char str[], int n)
{
	int len = strlen(str);
	n = n % len;
	for(int i = 0; i < n; ++i)
	{
		char c = str[i];
		int j = 0;
		for(j = i; j < len; j += n)
			str[j] = str[j+n];
		str[j-n] = c;
	}
}

如有错误,欢迎各位指出。

原文地址:https://www.cnblogs.com/littlethank/p/2316610.html