问题
汇编语言中有一种移位指令叫做循环左移(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;
}
};