思路:
用3个vector< pair< char,int > >保存str中每一组的字符及其下标
不用map因为map按照键排序,而vector可以按照插入顺序存储。
之后将3个vector的second转化为string,将string右旋即可
注意右旋string不能用拼接法,例如string长度为3,右旋5位,会导致下标越界
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
typedef pair<char,int> PCI;
int lei(char c){//判断字符类别
if(c >= 'a' && c <= 'i') return 1;
if(c >= 'j' && c <= 'r') return 2;
if((c >= 's' && c <= 'z') || c == '_') return 3;
return 0;
}
//将每组右旋k位
void rxuan(vector<PCI> &vec,int k){
string str;//存储vec中每个数的下标
for(auto x : vec){
str += x.second;
}
string cpy = str;//拷贝一份
//将下标右旋k位
for(int i = 0;i < str.size();i++){
str[i] = cpy[(i + k) % str.size()];
}
for(int i = 0;i < str.size();i++){
vec[i].second = str[i];
}
}
int main(){
cin.tie(0);
ios::sync_with_stdio(false);
int k1,k2,k3;
string str;
while(1){
cin>>k1>>k2>>k3;
if(k1 == 0 && k2 == 0 && k3 == 0) break;
cin>>str;
int len = str.size();
vector<PCI> vec1;//存放str中的第1组字符及其位置
vector<PCI> vec2;
vector<PCI> vec3;
for(int i = 0;i < str.size();i++){
if(lei(str[i]) == 1) vec1.push_back({str[i],i});
if(lei(str[i]) == 2) vec2.push_back({str[i],i});
if(lei(str[i]) == 3) vec3.push_back({str[i],i});
}
//右旋三组数据
rxuan(vec1,k1);
rxuan(vec2,k2);
rxuan(vec3,k3);
char ch[len + 10] = {0};//保存输出字符串
for(auto x : vec1){
ch[x.second] = x.first;
}
for(auto x : vec2){
ch[x.second] = x.first;
}
for(auto x : vec3){
ch[x.second] = x.first;
}
cout<<ch<<endl;
}
return 0;
}