一刷剑指offer(42)——翻转单词顺序VS左旋转字符串

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

思路:

分两步进行翻转:

1、翻转句子中所有的字符,此时不但翻转了句子中单词的顺序,单词内字符顺序也被翻转了。

2、翻转单词中字符的顺序

//翻转整个句子
void Reverse(char *pBegin,char *pEnd)
{
    if(pBegin==NULL || pEnd==NULL)
        return;
    while(pBegin<pEnd)
    {
        char temp=*pBegin;
        *pBegin=*pEnd;
        *pEnd=temp;
        pBegin++;
        pEnd--;
    }
}

//翻转整个句子之和,翻转每个单词
char* ReverseSentence(char *pData)
{
    if(pData==NULL)
        return NULL;
    char *pBegin=pData;
    char *pEnd=pData;
    while(*pEnd!='\0')
        pEnd++;
    pEnd--;
    //翻转整个句子
    Reverse(pBegin,pEnd);
    //翻转每个单词
    pBegin=pEnd=pData;
    while(*pBegin!='\0')
    {
        if(*pBegin==' ')
        {
            pBegin++;
            pEnd++;
        }
        else if(*pEnd==' ' || *pEnd=='\0')
        {
            Reverse(pBegin,--pEnd);     
            pBegin=++pEnd;
        }
        else
        {
            pEnd++;
        }
    }
    return pData;
}
题目:
字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部。请定义一个函数实现字符串左旋转操作的功能。比如输入"abcdefg"和数字2,则结果为"cdefgab"。

基于第一个题目的思路,假如输入“hello world”,翻转句子中单词顺序就可以得到“world hello",相当于把原始字符串左旋转了5个字符。

那么考虑"abcdefg",输入2,可以把它分成两个部分:前两个字符 、其他字符。

分别翻转这两个部分,得到:"bagfedc"。

再翻转整个字符串,得到:"cdefgab"。

可知只需要调用3次Reverse函数即可实现左旋转功能。

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;//a
            char* pFirstEnd=pStr+n-1;//b
            char* pSecondStart=pStr+n;//c
            char* pSecondEnd=pStr+nLength-1;//g
            //翻转前n个字符
            Reverse(pFirstStart,pFirstEnd);    
            //翻转剩余部分
            Reverse(pSecondStart,pSecondEnd);
            //翻转整个字符串
            Reverse(pFirstStart,pSecondEnd);
         }
    }
    retrun pStr;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值