HJ26 字符串排序(华为机试题)

记录一下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;
}

以上仅为做题笔记分享,如有错误,请多多包含。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值