用结构体把源字符串中是字母(不区分大小写)的位置和字符(都装成小写字母)存下来;

struct strw{
    int pos;
    char c;
    strw(int p,char cc):pos(p),c(cc){}
    inline bool operator<(const strw &v)const{
        if(c==v.c)return pos<v.pos;//如果字符相等,看位置靠前的(事先已经都转成小写字母)
        else return c<v.c;
    }
};
vector<strw> vec; //用vector存储结构体

最后一步,再输出时,如果字符是字母,按照vec进行输出;然后对比同位置的字符,如果是大写的,就把小写转成大写。

#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;
struct strw{
    int pos;
    char c;
    strw(int p,char cc):pos(p),c(cc){}
    inline bool operator<(const strw &v)const{
        if(c==v.c)return pos<v.pos;
        else return c<v.c;
    }
};
vector<strw> vec;
int main(){
    string s;
    while(getline(cin,s)){
        vec.clear();
        for(int i=0;i<s.size();i++){
            if((s[i]>='a'&&s[i]<='z') || (s[i]>='A'&&s[i]<='Z')){
                if(s[i]>='A'&&s[i]<='Z'){
                    vec.push_back(strw(i,char(s[i]-'A'+'a')));//都转成小写
                }else vec.push_back(strw(i,char(s[i])));
            }
        }sort(vec.begin(),vec.end());
        int j=0;
        for(int i=0;i<s.size();i++){
            if(s[i]>='a'&&s[i]<='z' || s[i]>='A'&&s[i]<='Z'){
                if(s[vec[j].pos]>='A'&&s[vec[j].pos]<='Z'){
                    cout<<char(vec[j].c-'a'+'A');
                }else cout<<vec[j].c;
                j++;
            }else{
                cout<<s[i];
            }
        }
        cout<<endl;
    } 
    return 0;
}