现在的位置: 首页 > 综合 > 正文

关于左旋转字符串的研究与实现

2018年03月31日 ⁄ 综合 ⁄ 共 1639字 ⁄ 字号 评论关闭

题目描述:将一个n元一维向量向左旋转i个位置。例如:当n=8且i=3时,向量abcdefgh旋转为defghabc。

其实这类问题方法有很多中,我就介绍两种比较特殊的方法:一种时间复杂度为O(n),空间复杂度O(1),另一种时间复杂度为O(1),空间复杂度为O(n)(以上空间复杂度不包括存储原字符串的空间)

方法一的思路:将字符串分为两个向量ab,a为前i-1个字符组成的向量,b为剩下字符组成的向量;首先将a逆序,得到a(r)b,再将b逆序,得到a(r)b(r),最后将整体逆序得到(a(r)b(r))(r) = ba;

例如字符串abcdefgh左旋转i=3,则a=abc,b=defgh

reverse(str, 0, i-1)  => cbadefgh

reverse(str, i, len-1) => cbahgfed

reverse(str, 0, len-1) => defghabc

这里有个细节需要注意,当i大于等于字符串的长度时,需要对i相对于len求余,即i = i%len

具体代码如下:

#include <iostream>
#include <cstring>
using namespace std;

void exch(char &a, char &b)	{ char temp = a; a=b; b=temp; }

void reverse(char *str, int start, int end)  //从start到end逆序str中的字符
{
	char *p=NULL;
	int i=start, j=end;
	while(i<j)
	{
		exch(*(str+i),*(str+j));
		i++;
		j--;	
	}
}

void rev_str(char *str, int shift)
{
	int len = strlen(str);
	if(shift>=len)	shift %= len;
	reverse(str, 0, shift-1);
	reverse(str, shift, len-1);
	reverse(str, 0, len-1);	
}

int main(void)
{
	const int SHIFT = 9;
	char str[100]="123456";
	rev_str(str, SHIFT);
	cout << str << endl;
	return 0;
}

方法二,典型的用空间换取时间

具体思路:申请一个与原字符串等大的内存空间的临时数组,首先将b向量(将字符串分为两个向量的思路与方法一等同)复制到临时数组中,再将a向量复制到临时数组中,最后将临时数组的内容复制到原字符串中

strncpy(temp, &str[shift], len-shift)

strnpy(&temp[len-shift], str, shift);

temp[len]='\0';                     //这是细节需要特别注意,因为之前temp并不是一个字符串,没有结束标志

strcpy(str, temp);

具体实现代码如下:

#include <iostream>
#include <cstring>
#include <cstdlib>
using namespace std;

void rev_str(char *str, int shift)
{
	int step=0;
	int len = strlen(str);
	shift = shift>=len ? shift%len : shift;
	char *temp = (char *)malloc(len+1);
	//在内存中进行相应位置的拷贝字符,从而达到字符旋转的目的
	strncpy(temp, &str[shift], len-shift);
	strncpy(&temp[len-shift], str, shift);
	temp[len]='\0';
	strcpy(str, temp);
}
int main(void)
{
	const int SHIFT = 2;
	char str[] = "123456";
	rev_str(str, SHIFT);
	cout << str << endl;
	return 0;
}

以上方法知识其中的两种,若有更好的方法,或者我的方法有什么不妥,可以与我交流,互相学习!

抱歉!评论已关闭.