剑指offer 阅读笔记 左旋转字符串

剑指offer 面试题 41_2   左旋转字符串字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部,请定义一个函数实现字符串左旋转操作的功能。比如输入字符串"abcdefg" 和2,该函数将返回旋转2位得到的结果“cdefgab”。 改天记录和书中不一样的解法。

    书中思路是求字符串长度,然后求子串分割点。因为自己不擅长使用字符串函数,所以这里不求字符串长度,利用传入的n确定子串分割点。

     该题的基础是有一个旋转函数,指定起始指针和结束指针,实现从起始到结束的旋转,比如对于"abcdefg" ,旋转之后返回“gfedcba”。 有了这个思路,对字符串实现左旋转,可以先旋转整个字符串,然后分别旋转子串,你如对于" abcdefg" ,整个旋转之后是“gfedcba”,然后我们再分别对“gfedc”和“ba”旋转,就得到cdefgab"。

      那么这里的重点就是找到分割点,比如整个字符串旋转之后,旋转前面一部分,我们让pEnd指向最后一个字符b,然后往前移动n位,比如此题2,位,就指向了g,所以此时传给reverse函数pBegin为c,pEnd指向g则实现了前面的反转,然后赋值pBegin = ++pEnd,则pBegin就指向了a,然后让pEnd再次指向最后b,调用reverse函数就反转了ba。经过三次旋转之后字符串就为 cdefgab",即完成了左旋转。当然要注意特殊情况的判断。代码如下:

char* LeftRotateString( char* pStr,int n)
{
	if (pStr == NULL || n<= 0)
	{
		return pStr ;
	}
    //首先整个字符串翻转
	char * pStart = pStr ;
	char* pEnd = pStr ;
	while( *pEnd != '\0')
	{
		pEnd ++ ;
	}
	pEnd -- ;
	Reverse(pStart,pEnd) ;
	分别对两部分翻转,重要的是确定两个子串的开始结束指针
	while(n > 0)
	{
        pEnd -- ;
		n--;
	}
	///此时pend指向前面子串的尾部
	Reverse(pStart ,pEnd);
	if (*(pEnd +1 ) != '\0')
	{
		pStart = ++pEnd ;
	}
	
	while(*pEnd != '\0')
	{
		pEnd ++ ;
	}
	pEnd -- ;
	Reverse(pStart ,pEnd);
	return pStr ;

}

书中代码:

char* LeftRotateString(char* pStr, int n)
{
    if(pStr != NULL)
    {
        int nLength = static_cast<int>(strlen(pStr));
        if(nLength > 0 && n > 0 && n < nLength)
        {
            char* pFirstStart = pStr;
            char* pFirstEnd = pStr + n - 1;
            char* pSecondStart = pStr + n;
            char* pSecondEnd = pStr + nLength - 1;

            // 翻转字符串的前面n个字符
            Reverse(pFirstStart, pFirstEnd);
            // 翻转字符串的后面部分
            Reverse(pSecondStart, pSecondEnd);
            // 翻转整个字符串
            Reverse(pFirstStart, pSecondEnd);
        }
    }

    return pStr;
}
书中代码虽然简洁,但是变量多。

reverse函数代码如下:
void Reverse(char *pBegin, char *pEnd)
{
    if(pBegin == NULL || pEnd == NULL)
        return;

    while(pBegin < pEnd)
    {
        char temp = *pBegin;
        *pBegin = *pEnd;
        *pEnd = temp;

        pBegin ++, pEnd --;
    }
}
这里只是关键函数代码,完整工程请私信哈。


    

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值