题目:
题目描述
字符串的右旋转操作是把字符串尾部的若干个字符转移到字符串的前面。给定一个字符串 s 和一个正整数 k,请编写一个函数,将字符串中的后面 k 个字符移到字符串的前面,实现字符串的右旋转操作。
例如,对于输入字符串 "abcdefg" 和整数 2,函数应该将其转换为 "fgabcde"。
输入描述
输入共包含两行,第一行为一个正整数 k,代表右旋转的位数。第二行为字符串 s,代表需要旋转的字符串。
输出描述
输出共一行,为进行了右旋转操作后的字符串。
输入示例
2
abcdefg
输出示例
fgabcde
提示信息
数据范围:
1 <= k < 10000,
1 <= s.length < 10000;
思路:
看到字符串反转,移动一类
首先会想到指针或者reverse方法
两种都比较好实现
只要思路对,代码秒AC
解题过程
1.指针
本来想使用双指针从后更新元素,再将所需移动的元素填入前端空出来的位置
编写实现过程中发现
1.必须要定义一个新的容器来存储待移动元素,不然从后覆盖会导致这部分丢失
2.记录和后移过程不能同时进行,他们的长度是不一样的
那么解决这些问题就需要先定义一个数组之类的,虽然已知这个容器的大小为k
但k是变量,不能直接定义一个大小为k的字符数组用于保存待移动元素
只能使用vector动态申请内存
然后使用三个for循环,分别用于记录待移动的元素、移动元素,实现右旋
是很笨很笨很浪费空间时间的方法了。。。。
具体代码如下
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int main(){
int k;
cin>>k;
string s;
cin>>s;
int len=s.size();
不太高明之想用双指针但发现不适用版
//需要一个可以存放被移动元素的数组?字符串?
//并且大小已知为k,但k是变量不能直接用数组定义
//动态申请内存
vector<char> t(k);
// 记录被移动的元素,从 t 的第 k-1 位开始倒序存储
for(int j = len - 1, i = k - 1; j >= len - k; j--, i--){
t[i] = s[j];
}
for(int j=len-1;j>=k;j--){
//移动元素
s[j]=s[j-k];
}
//记录被移动元素和移动元素不能同时进行
//他们所操作的元素个数并不相同
for(int i=0;i<k;i++){
s[i]=t[i];
}
cout<<s<<endl;
retrun 0;
}
2.reverse方法
可以先思考右旋和反转间的关系
本题相当于对两串字符串实现对调
但没有对应库函数可以实现
那么这里用个巧思
先局部局部反转
再整体反转就可以得到正确结果
用样例说明
初始输入:abcdefg
反转前一段:edcbafg
反转后一段:edcbagf
全部反转:fgabcde
当然先整体再前一段再后一段也是一样的
只需要确保反转位置无误即可
具体代码如下
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int main(){
int k;
cin>>k;
string s;
cin>>s;
int len=s.size();
//使用反转
//可以说是聪明人才想的到的巧妙转法
// 先反转前一段,长度len-n ,
reverse(s.begin(), s.begin() + len - k);
// 再反转后一段
reverse(s.begin() + len - k, s.end());
// 整体反转
reverse(s.begin(), s.end());
cout<<s<<endl;
return 0;
}