zoukankan      html  css  js  c++  java
  • 字符串的旋转 (增改版)

    更多方法:http://blog.csdn.net/v_JULY_v/article/details/6322882

    题目描述:给定一个字符串,要求将字符串前面的若干个字符移动到字符串的尾部。例如,将字符串"abcdef"的前3个字符'a'、'b'、'c'移动到字符串的尾部,那么原字符串将变成"defabc"。请写一个函数实现此功能。

      方法一:蛮力移位

    定义指向字符串的指针s,设字符串长度为n,首先实现LeftShiftOne(char *s ,int n)将一个字符移动到字符串的最后,然后调用m次实现将m个字符移动到字符串末尾

    参考代码:

    #include <bits/stdc++.h>
    
    using namespace std;
    
    void LeftShiftOne( char* s , int n )
    {
        char t = s[0];
        for( int i = 1 ; i < n ; i++ )
        {
            s[i-1] = s[i];
        }
        s[n-1] = t;
    }
    void LeftRotateString( char* s , int n , int m )
    {
        while( m-- )
        {
            LeftShiftOne( s , n );
        }
    }
    
    int main()
    {
        char str[]="abcdef";
        cout<<str<<endl;
        LeftRotateString( str , 6 , 3 );
        cout<<str<<endl;
    }

    GCC运行结果:

      方法二:三步翻转

    拿上面的例子来说明:

    (1)将原来的字符划分为两个部分A和B(划分依据为所移动m个字符);

    (2)将子字符串A和B进行翻转操作;  分别为:"abc"--->"cba"  "def"--->"fed"

    (3)最后将整体字符串进行翻转操作,从而实现题目要求的字符串翻转.  过程为: "cbafed"--->"defabc"

    参考代码:

    #include <bits/stdc++.h>
    
    using namespace std;
    
    void ReverseString( char *s , int from , int to )
    {
        while( from < to )
        {
            char t = s[from];
            s[from++] = s[to];
            s[to--] = t;
        }
    }
    void LeftRotateString( char *s , int n , int m )
    {
        m%=n;
        ReverseString(s,0,m-1);
        ReverseString(s,m,n-1);
        ReverseString(s,0,n-1);
    }
    int main()
    {
        char str[]="abcdef";
        cout<<str<<endl;
        LeftRotateString(str,6,3);
        cout<<str<<endl;
    }

    GCC运行结果:

     方法三:指针翻转法 (感谢网友我非英雄的留言) 编程珠玑上还有另外一种解法,拿abcdef来说,保存a,将d移到a的位置,空出来的d的位置放a,a的位置空下来,放置e,依次遍历完abc

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

    解题思路:

    1、首先让p1=ch[0],p2=ch[m],即让p1,p2相隔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++;

    参考代码:

    #include<bits/stdc++.h>
    
    using namespace std;
    
    void RemoveString(char *s, int m)
    {
        int len = strlen(s);
        if (len== 0 || m <= 0)
            return;
    
        if (m % len <= 0)
            return;
    
        int p1 = 0;
        int p2 = m;
        int k = (len - m) - len % m;
    
        while (k --)
        {
            swap(s[p1], s[p2]);
            p1++;
            p2++;
        }
    
        int r = len - p2;
        while (r--)
        {
            int i = p2;
            while (i > p1)
            {
                swap(s[i], s[i-1]);
                i--;
            }
            p2++;
            p1++;
        }
    }
    
    int main()
    {
        char ch[]="abcdef";
        cout<<ch<<endl;
        RemoveString(ch,3);
        cout<<ch<<endl;
        return 0;
    }

    GCC运行结果:

  • 相关阅读:
    【java】i++与++i、i--运算
    配置ssh框架启动tomcat服务器报异常Unable to create requested service [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment]
    jsp页面第一句话报这个错Syntax error, insert "}" to complete
    oracle忘记密码用户名被锁定_解决方案
    关于c#的单例模式,static 变量,下面一篇很不错
    Entity Framework 冲突检测,这一篇我看了比较明了
    关于lambda表达式与使用局部变量的作用域问题,下面这篇不错
    C# SelectMany 的使用
    UML类图 入门 (转载)
    VS code key shortcuts for windows
  • 原文地址:https://www.cnblogs.com/zpfbuaa/p/5330421.html
Copyright © 2011-2022 走看看