记录一下stable_sort()的自定义排序用法。
前言:
stable_sort()底层使用归并排序,是一种稳定的排序算法,即排序完相等的元素不会改变其相对位置,第三个参数可以自定义排序方法。
题目要求:
编写一个程序,将输入字符串中的字符按如下规则排序。
规则 1 :英文字母从 A 到 Z 排列,不区分大小写。
如,输入: Type 输出: epTy
规则 2 :同一个英文字母的大小写同时存在时,按照输入顺序排列。
如,输入: BabA 输出: aABb
规则 3 :非英文字母的其它字符保持原来的位置。
如,输入: By?e 输出: Be?y
输入描述:
输入字符串
输出描述:
输出字符串
示例:
输入:
A Famous Saying: Much Ado About Nothing (2012/8).
输出:
A aaAAbc dFgghh: iimM nNn oooos Sttuuuy (2012/8).
思路:
首先规则2提示排序前后相对顺序不变,则考虑到使用稳定排序,有冒泡排序、插入排序、归并排序等可用,同时STL内置了stable_sort()排序方法,考虑到做题的便利性,遂尝之。
其次规则1提示我们需要进行自定义排序,即:
static bool cmp(char a, char b){
if(a>=97 && a<=122 && b>=97 && b<=122)return a<b;
else if(a>=97 && a<=122 && b>=65 && b<=90) return (a-32)<b;
else if(a>=65 && a<=90 && b>=65 && b<=90) return a<b;
else if(a>=65 && a<=90 && b>=97 && b<=122) return a<(b-32);
else return a<b;
}
最后规则3要求“非英文字母的其它字符保持原来的位置”,答主最开始考虑将整个输入的string进行自定义排序(想少点空间复杂度),但是尝试以后bug满满,遂放弃(太菜),于是选择新建一个vector(string均可)存放所有的char,仅对字符排序,后面再进行反向替换:
vector<int>vec;
for(int i = 0;i<str.size();i++){
if((str[i] >=65 && str[i]<=90) ||(str[i]>=97 &&str[i]<=122))vec.emplace_back(str[i]);
}
最终代码:
#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
using namespace std;
class Solution{
public:
//自定义稳定排序,类内定义需要写成static类型,当然cmp写成仿函数也可
static bool cmp(char a, char b){
if(a>=97 && a<=122 && b>=97 && b<=122)return a<b;
else if(a>=97 && a<=122 && b>=65 && b<=90) return (a-32)<b;
else if(a>=65 && a<=90 && b>=65 && b<=90) return a<b;
else if(a>=65 && a<=90 && b>=97 && b<=122) return a<(b-32);
else return a<b;
}
string func(string& str){
vector<int>vec;
for(int i = 0;i<str.size();i++){
if((str[i] >=65 && str[i]<=90) ||(str[i]>=97 &&str[i]<=122))vec.emplace_back(str[i]);
}
stable_sort(vec.begin(),vec.end(),cmp);
//双指针反向替换
for(int i = 0, j = 0;i<str.size();i++){
if((str[i] >=65 && str[i]<=90) ||(str[i]>=97 &&str[i]<=122)){
str[i] = vec[j];
j++;
}
}
return str;
}
};
int main() {
string str;
getline(cin,str);
Solution s;
cout<<s.func(str);
return 0;
}
额外备注:
最近做题遇到过对二维数组的自定义排序问题:
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
class cmp {
public:
bool operator()(vector<int>&a, vector<int>&b) {
//根据vec的第二元素 从小到大排序
return a[1] < b[1];
}
};
int main(){
vector<vector<int>>vec = {{1,3},{2,2},{3,1},{4,5},{5,4}};
sort(vec.begin(),vec.end(),cmp());
// 排序完成:vec = {{3,1},{2,2},{1,3},{5,4},{4,5}}
return 0;
}
以上仅为做题笔记分享,如有错误,请多多包含。