Fork me on GitHub

字符串的旋转 (增改版)

更多方法: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运行结果:

posted @ 2016-03-28 20:18  伊甸一点  阅读(360)  评论(1编辑  收藏  举报