挑战面试编程:左移字符串

                         挑战面试编程:左移字符串

问题描述:

左移字符串:如有字符串“abcdefg”,可把它看作是一首尾相连的字符串,左移三个字符后,变为“defgabc”,请编程实现。

方法一:

利用额外的内存空间,实现中转。

步骤1:把“abc”存储到额外空间;

步骤2:把“defg”移动到字符串的首部。至此,“defg”到达最终位置。

步骤3:把“abc”strcat到“defg”的尾部。

char *leftMove(char *s, int n)
{
	if (NULL == s || n <= 0 || n >= strlen(s)) return s;
	int L = strlen(s);
	char *tmp = malloc(sizeof(char)*L);
	strncpy(tmp, s, n);   //步骤1
	tmp[n] = 0;
	memmove(s, s + n, L - n + 1);   //步骤2,移动的字节数是L-n+1(包含最后的结束符)
	strcat(s, tmp);      //步骤3
	free(tmp);
	return s;
}


时、空复杂度都是O(n)。n是字符串的长度。     


方法二:

比较巧妙,把s[0]存储到中间变量t,然后把s[n]存放到s[0],s[2n]存放到s[n],……直到s[0]存放到...。下标每次变化n,显然是需要对L求余的。

char *leftMove1(char *s, int n)
{
	if (NULL == s || n <= 0 || n >= strlen(s)) return s;
	int i1, i2, L;
	char c;
	c = s[0];
	L = strlen(s);
	i1 = n % L;
	i2 = 0;
	while (i1)
	{
		s[i2] = s[i1];
		i2 = i1;
		i1 = (i1 + n) % L;
	}
	s[i2] = c;
	return s;
}

每个元素都移动了一次,时间复杂度是O(n);只使用了一个中间变量,空间复杂度是O(1)。


方法三:

把问题抽象化,s=XY,X=“abc”,Y=“defg”。最后实现s=YX。

X'是X的逆置,Y'是Y的逆置。(X'Y')'=Y''X''=YX。

以上是类似数学上的一个推理过程。

char *reverse(char *s, int n)
{
	if (NULL == s || n <= 0 || n > strlen(s)) return s;
	int left, right;
	char c;
	left = 0, right = n - 1;
	while (left < right)
	{
		c = s[left];
		s[left] = s[right];
		s[right] = c;
		left++;
		right--;
	}
	return s;
}
char *leftMove(char *s, int n)
{
	if (NULL == s || n <= 0 || n >= strlen(s)) return s;
	int L = strlen(s);
	reverse(s, n);
	reverse(s + n, L - n);
	reverse(s, L);
	return s;
}


思考题:

1.右移又该如何处理?


所有内容的目录

  • CCPP Blog 目录       


你可能感兴趣的:(面试,字符串,左移)