左旋转字符串

问题

汇编语言中有一种移位指令叫做循环左移(ROL),现在有个简单的任务,就是用字符串模拟这个指令的运算结果。对于一个给定的字符序列S,请你把其循环左移K位后的序列输出。例如,字符序列S=”abcXYZdef”,要求输出循环左移3位后的结果,即“XYZdefabc”。

方法一:

将字符串的第一个字符赋值给一个临时char型的变量,再将字符串后面的每一位依次向前移动,最后将这个临时变量放到字符串最后一位,这样就完成了左移一次的操作,多次操作就可以左移n次

class Solution {
public:
    string LeftRotateString(string str, int n) 
    {
        int len=str.size();
        if(len==0) return str;
        if(n<0) return str;
        if(n>=len) n=n%len;

        for(int i=1;i<=n;i++)
        {
            char tmp=str[0];
            for(int j=0;j<len-1;j++)
                str[j]=str[j+1];
            str[len-1]=tmp;
        }
        return str;
    }
};

方法二

用substr()函数获得字符串的前n个字符,再用erase函数去除字符串的前n个字符,最后将获取的前n个字符加到该字符串上

C++中substr函数的用法:

  • 形式:s.substr(pos, n)
  • 解释:返回一个string,包含s中从pos开始的n个字符的拷贝(pos的默认值是0,n的默认值是s.size()-pos,即不加参数会默认拷贝整个s)
  • 补充:若pos的值超过了string的大小,则substr函数会抛出一个out_of_range异常;若pos+n的值超过了string的大小,则substr会调整n的值,只拷贝到string的末尾

C++中erase函数的用法:

  • erase(pos,n); 删除从pos开始的n个字符,比如erase(0,1)就是删除第一个字符
  • erase(position);删除position处的一个字符(position是个string类型的迭代器)
  • erase(first,last);删除从first到last之间的字符(first和last都是迭代器)

下面给出一个例子

#include <iostream>
#include <string>
using namespace std;
int main ()
{
  string str ("This is an example phrase.");
  string::iterator it;

  // 第(1)种用法
  str.erase (10,8);
  cout << str << endl;        // "This is an phrase."

  // 第(2)种用法
  it=str.begin()+9;
  str.erase (it);
  cout << str << endl;        // "This is a phrase."

  // 第(3)种用法
  str.erase (str.begin()+5, str.end()-7);
  cout << str << endl;        // "This phrase."
  return 0;
}

言归正传,看该题的解法

class Solution {
public:
    string LeftRotateString(string str, int n) 
    {
        int len=str.size();
        if(len==0) return str;
        if(n<0) return str;
        if(n>=len) n=n%len;

        string tmp=str.substr(0,n);
        str.erase(0,n);
        str=str+tmp;
        return str;
    }
};

同样的使用substr函数,可以将两个相同的字符串连接起来,再用substr函数取连接之后字符串的从第n位开始的长度为原字符串长度的字符串

class Solution {
public:
    string LeftRotateString(string str, int n) 
    {
        int len=str.size();
        if(len==0) return str;
        if(n<0) return str;
        n=n%len;

        str=str+str;
        return str.substr(n,len);
    }
};

方法三

将前n个字符串首尾调换,再将后面的字符串首位调换,最后将整个字符串首尾调换

class Solution {
public:
    string LeftRotateString(string str, int n) 
    {
        int len=str.size();
        if(len==0) return str;
        if(n<0) return str;
        if(n>=len) n=n%len;

        reverse(str,0,n-1);    // 翻转字符串的前面n个字符
        reverse(str,n,len-1);  // 翻转字符串的后面部分
        reverse(str,0,len-1);   // 翻转整个字符串
        return str;
    }

    void reverse(string &str,int start,int end)
    //str一定要用引用,否则参数无法传递
    {
        while(start<end)
        {
            char tmp=str[start];
            str[start]=str[end];
            str[end]=tmp;
            start++;
            end--;
        }
    }
};

方法四

新建一个字符串s,将原字符串的第n+1位到最后一位用push_back塞入s中,再将前n位用push_back塞入s中,返回s

class Solution {
public:
    string LeftRotateString(string str, int n) 
    {
        int len=str.size();
        if(len==0) return str;
        if(n<0) return str;
        n=n%len;

        string s;
        for(int i=n;i<len;i++)
            s.push_back(str[i]);
        for(int i=0;i<n;i++)
            s.push_back(str[i]);
        return s;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值