• 左旋转字符串


    来源:http://blog.csdn.net/v_july_v/article/details/6322882

    题目描述
    定义字符串的左旋转操作:把字符串前面的若干个字符移动到字符串的尾部,如把字符串abcdef左旋转2位得到字符串cdefab。请实现字符串左旋转的函数

    指针翻转法

        咱们先来看个例子,如下:abc defghi,若要让abc移动至最后的过程可以是:abc defghi->def abcghi->def ghiabc

        如此,我们可定义俩指针,p1指向ch[0],p2指向ch[m];
    一下过程循环m次,交换p1和p2所指元素,然后p1++, p2++;。

    1. 第一步,交换abc 和def ,abc defghi->def abcghi
    2. 第二步,交换abc 和 ghi,def abcghi->def ghiabc

        整个过程,看起来,就是abc 一步一步 向后移动

    • abc defghi
    • def abcghi
    • def ghi abc  

      //最后的 复杂度是O(m+n)  

    图解如下:

        由上述例子九个元素的序列abcdefghi,您已经看到,m=3时,p2恰好指到了数组最后一个元素,于是,上述思路没有问题。但如果上面例子中i 的后面还有元素列?

        即,如果是要左旋十个元素的序列:abcdefghij,ok,下面,就举这个例子,对abcdefghij序列进行左旋转操作:

    如果abcdef ghij要变成defghij abc:
      abcdef ghij
    1. def abc ghij
    2. def ghi abc j      //接下来,j 步步前移
    3. def ghi ab jc
    4. def ghi a j bc
    5. def ghi j abc 

     下面,再针对上述过程,画个图清晰说明下,如下所示:

      ok,咱们来好好彻底总结一下此思路二(就4点,请仔细阅读)

    1、首先让p1=ch[0]p2=ch[m],即让p1p2相隔m的距离;

    2、判断p2+m-1是否越界,如果没有越界转到3,否则转到4(abcdefgh这8个字母的字符串,以4左旋,那么初始时p2指向e,p2+4越界了,但事实上p2至p2+m-1是m个字符,可以再做一个交换)

    3、不断交换*p1*p2,然后p1++p2++,循环m次,然后转到2

    4、此时p2+m-1 已经越界,在此只需处理尾巴。过程如下:

       4.1 通过n-p2得到p2与尾部之间元素个数r,即我们要前移的元素个数。

       4.2 以下过程执行r次:

           ch[p2]<->ch[p2-1],ch[p2-1]<->ch[p2-2]....ch[p1+1]<->ch[p1]p1++p2++

     

     

    //copyright@July、颜沙    
    //最终代码,July,updated again,2011.04.17。    
    #include <iostream>    
    #include <string>    
    using namespace std;    
        
    void rotate(string &str, int m)    
    {    
            
        if (str.length() == 0 || m <= 0)    
            return;    
            
        int n = str.length();    
            
        if (m % n <= 0)    
            return;    
            
        int p1 = 0, p2 = m;    
        int k = (n - m) - n % m;    
            
        // 交换p1,p2指向的元素,然后移动p1,p2    
        while (k --)     
        {    
            swap(str[p1], str[p2]);    
            p1++;    
            p2++;    
        }    
            
        // 重点,都在下述几行。    
        // 处理尾部,r为尾部左移次数    
        int r = n - p2;    
        while (r--)    
        {    
            int i = p2;    
            while (i > p1)    
            {    
                swap(str[i], str[i-1]);    
                i--;    
            }    
            p2++;    
            p1++;    
        }    
        //比如一个例子,abcdefghijk    
        //                    p1    p2    
        //当执行到这里时,defghi a b c j k    
        //p2+m出界 了,    
        //r=n-p2=2,所以以下过程,要执行循环俩次。    
            
        //第一次:j 步步前移,abcjk->abjck->ajbck->jabck    
        //然后,p1++,p2++,p1指a,p2指k。    
        //               p1    p2    
        //第二次:defghi j a b c k    
        //同理,此后,k步步前移,abck->abkc->akbc->kabc。    
    }    
        
    int main()       
    {       
        string ch="abcdefghijk";       
        rotate(ch,3);       
        cout<<ch<<endl;       
        return 0;          
    }    

     

     

  • 相关阅读:
    webpack管理资源
    webpack缓存
    webpack起步
    openssl命令使用
    linux系统安装中文字体-----
    HTML转成PDF的4个前端方法----但都被我拒绝了,我选择后端方法(这才是吊!)
    HTML页面如何导出pdf
    为什么装了easyless插件,vscode还是不能用?
    JSON格式错误,json_decode中true和JSON_UNESCAPED_SLASHES的用法
    tp5条件判断,in,notin,between,if等
  • 原文地址:https://www.cnblogs.com/heyonggang/p/3401448.html
Copyright © 2020-2023  润新知