剑指offer-面试题42:翻转单词顺序VS左旋转字符串

题目一:输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变。为简单起见,标点符号和普通字母一样处理。例如输入字符串“I am a student.",则输出"student. a am I"。

思路:《编程珠玑》第二章有类似题目,思路就是先翻转每个单词,然后再翻转整体。

void Reverse(char* pStart, char* pEnd)
{
    if(pStart == NULL || pEnd == NULL)
        return;
    
    while(pStart < pEnd)
    {
        char temp = *pStart;
        *pStart = *pEnd;
        *pEnd = temp;
        ++pStart;
        --pEnd;
    }
}

void ReverseSentence(char* pStr)
{
    if(pStr == NULL)
        return;
    
    int length = strlen(pStr);
    char *pStart, *pEnd;
    pStart = pEnd = pStr;
    while(*pStart != '\0')
    {
        while(*pStart == ' ')
            ++pStart;
        pEnd = pStart;
        while(*pEnd != ' ' || *pEnd != '\0')
		{
            ++pEnd;
			if(*pEnd == ' ' || *pEnd == '\0')
				break;
		}
        Reverse(pStart, --pEnd);
        pStart = ++pEnd;
    }
    Reverse(pStr, pStr+length-1);
}
题目二:字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部。请定义一个函数实现字符串左旋转操作的功能。比如输入字符串"abcdefg"和数字2,该函数将返回左旋转2位得到的结果“cdefgab"。

思路(1):与题目一类似,可以把前面两位看成一个单词,后面的部分看成另一个单词,那么问题就成了翻转两个单词而单词内的字符顺序不变。仿照上一题的做法,先翻转ab部分得到"bacdefg",再翻转后面的部分得到"bagfedc",最后翻转整体得到"cdefgab”,即完成了两位的左旋转。

char* Rotate(char* pStr, int n)
{
	int length = strlen(pStr);
	if(pStr != NULL && n > 0 && n < length)
	{
		char* subStr1Begin = pStr;
		char* subStr1End = pStr + n - 1;
		char* subStr2Begin = subStr1End + 1;
		char* subStr2End = pStr + length - 1;

		Reverse(subStr1Begin, subStr1End);
		Reverse(subStr2Begin, subStr2End);
		Reverse(subStr1Begin, subStr2End);
	}
	return pStr;
}
思路(2):注意到翻转实际上就是字符的移位,翻转2位就是下标整体向前移动2位,譬如'c'原先的下标为2,翻转后为0。我们把n位上的移到0位上,注意0位上的字符暂时不需要移动,所以保存在一个临时变量中;再把2n位移到n位,3n位移到2n位(所有下标都要取模),直到需要0位时,因为0位已经n位被覆盖,但是先前的值已经保存在临时变量中,把这个临时变量放在新位置中。注意这一过程并不一定所有元素都发生了移动,如果移动的字符小于字符串长度,那么再从第1位开始,n+1位移到1位上……直到所有位都发生了移动。

char* rotate(char* pStr, int n)
{
    if(pStr != NULL && n > 0)
    {
        int length = strlen(pStr);
        int countOfSwaped = 0;
        int startOfSwap = 0;
        int index = startOfSwap;
        while(countOfSwaped < length)
        {
        	char temp = pStr[index];
        	int newIndex = (index+n) % length;
        	
        	while(newIndex != startOfSwap)
        	{
        	 	pStr[index] = pStr[newIndex];
        	 	++countOfSwaped;
            	index = newIndex;
            	newIndex = (newIndex+n) % length;
        	}
        	pStr[index] = temp;
        	++countOfSwaped;
        	
        	if(countOfSwaped < length)
        		index = ++startOfSwap;
        }
    }
    return pStr;
}






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值