您的位置:首页 > Web前端

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

2016-07-06 18:31 281 查看
剑指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 --;
}
}
这里只是关键函数代码,完整工程请私信哈。

    
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  C++ 字符串 旋转