🌟【C++ 进阶】告别繁琐的 cmp 函数:用 Lambda 表达式秒杀“多级排序”

📍 场景引入

在算法竞赛或日常开发中,我们经常遇到多条件排序的需求。例如:

  1. 按距离某个值 XXX 的绝对值大小升序排;
  2. 若距离相同,再按数字本身的大小升序排。

传统的做法是写一个全局 bool cmp 函数,或者重载 structoperator<。但这种做法在处理“局部变量”(如 XXX)时非常痛苦。今天分享一个现代 C++ 的神器——Lambda 表达式


💡 核心武器:Lambda 表达式

std::sort 的第三个参数中,我们可以直接插入一段“现场逻辑”:

sort(a.begin(), a.end(), [x](int n1, int n2) {
    // 逻辑写在这里
});

[x] (捕获列表): 最关键的部分!它能把 main 函数里的局部变量 xxx “抓”进来给排序规则使用。
(int n1, int n2): 待比较的两个元素。


💻 实战代码:按绝对值差排序

#include <iostream>
#include <vector>
#include <cmath>
#include <algorithm>

using namespace std;

int main() {
    int n, x;
    cin >> n >> x;
    vector<int> a(n);
    for(int i=0; i<n; i++) cin >> a[i];

    // 🚀 一行 Lambda 秒杀多级排序
    sort(a.begin(), a.end(), [x](int n1, int n2) {
        int d1 = abs(n1 - x);
        int d2 = abs(n2 - x);
        
        if (d1 != d2) return d1 < d2; // 第一优先级:差值升序
        return n1 < n2;               // 第二优先级:数值升序
    });

    for(int v : a) cout << v << " ";
    return 0;
}

🏆 为什么推荐 Lambda?

1.高内聚: 逻辑就在 sort 旁边,不用满世界找 cmp 定义。
2.闭包能力: 只有 Lambda 能轻松访问 main 函数里的动态变量。
3.多级清爽: 不管有几级排序,用 if 嵌套写出来非常直观。


第二部分:秒杀《学生成绩多级排序》题

记得咱们之前的学生成绩排序吗?
题目规则:

  1. 分数(Score) 从高到低排(降序);
  2. 若分数相同,按 姓名(Name) 字典序从小到大排(升序)。

传统写法需要定义 struct 并在外部写 cmp
Lambda 绝杀写法只需要在 main 里面这样写:

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>

using namespace std;

struct Student {
    string name;
    int score;
};

int main() {
    int n;
    cin >> n;
    vector<Student> sts(n);
    for(int i=0; i<n; i++) cin >> sts[i].name >> sts[i].score;

    // 🚀 Lambda 秒杀开始!
    sort(sts.begin(), sts.end(), [](const Student& s1, const Student& s2) {
        // 第一优先级:分数降序
        if (s1.score != s2.score) {
            return s1.score > s2.score; 
        }
        // 第二优先级:姓名升序
        return s1.name < s2.name; 
    });

    // 输出结果
    for(auto& s : sts) {
        cout << s.name << " " << s.score << endl;
    }

    return 0;
}

🧠 为什么这叫“秒杀”?

1.不用跳出主函数: 你的思路不用从 main 跳到外面写函数,再跳回来。
2.类型安全: Lambda 里的 const Student& 保证了排序过程不会产生多余的拷贝,速度极快。
3.可读性极强: 读这段代码就像读英语作文——“如果分数不同,返回 s1 > s2;否则返回姓名升序”。

更多推荐