当前位置: 首页 > news >正文

C++ 比较器(Comparator)超详细笔记

1. 什么是比较器?

  • 定义:一个二元函数(或函数对象),接收两个元素 a, b,返回 bool

  • 作用:告诉排序算法“谁应该排在前面”。

  • 调用场景

    • std::sort / std::stable_sort / std::set / std::priority_queue 等。


2. 三种写法速查表

写法示例推荐场景
普通函数bool cmp(int a,int b){return a>b;}快速刷题
仿函数 / 函数对象struct Cmp{bool operator()(const T&a,const T&b)const{...}};需要状态、可复用
Lambdasort(v.begin(),v.end(),[](const T&a,const T&b){...});C++11+ 最常用

3. 核心规则:严格弱序(Strict Weak Ordering)

必须同时满足 4 条铁律,否则 UB(未定义行为):

名称用符号 < 描述违反示例
非自反!(a < a) 永远成立return a <= b; ❌
非对称a < b ⇒ !(b < a)return a < b && b < a; ❌
可传递a < b ∧ b < c ⇒ a < c逻辑不自洽
可比较!(a < b) ∧ !(b < a) ⇒ a、b 等价

4. 升序 vs 降序模板

4.1 单关键字

// 升序
bool up(int a,int b){return a < b;}
// 降序
bool down(int a,int b){return a > b;}

4.2 多关键字(以结构体为例)

struct Node{int l,r,id;};// 升序:先 l 小,再 r 小
bool cmp_up(const Node&x,const Node&y){if(x.l!=y.l) return x.l < y.l;return x.r < y.r;
}// 降序:先 l 大,再 r 大
bool cmp_down(const Node&x,const Node&y){if(x.l!=y.l) return x.l > y.l;return x.r > y.r;
}

5. Lambda 捕获与内联

int base = 100;
sort(v.begin(), v.end(), [base](const int& x, const int& y){return abs(x - base) < abs(y - base); // 距离 base 升序
});

6. 典型错误 Top3

错误后果修复
用 <= / >=死循环/RE改成 < 或 >
修改全局变量UB保持纯函数
捕获引用悬空野值用值捕获或延长生命周期

7. 容器专用比较器

7.1 std::set

struct Node{int l,r;};
struct Cmp{bool operator()(const Node&a,const Node&b)const{if(a.l!=b.l) return a.l<b.l;return a.r<b.r;}
};
set<Node,Cmp> s;   // 自定义排序的 set

7.2 priority_queue

auto cmp=[](const Node&a,const Node&b){return a.l>b.l;};
priority_queue<Node,vector<Node>,decltype(cmp)> pq(cmp); // 小根堆

8. 记忆口诀

“返回 bool,严格弱序;升序用 <,降序用 >;多键先主后副,别踩 <= 坑。”


9. 一页速查卡片(可复制到代码模板)

// 单关键字升序
auto cmp1=[](int a,int b){return a<b;};// 单关键字降序
auto cmp2=[](int a,int b){return a>b;};// 多关键字升序
auto cmp3=[](const Node&x,const Node&y){if(x.l!=y.l) return x.l<y.l;if(x.r!=y.r) return x.r<y.r;return x.id<y.id;
};// 多关键字降序
auto cmp4=[](const Node&x,const Node&y){if(x.l!=y.l) return x.l>y.l;if(x.r!=y.r) return x.r>y.r;return x.id>y.id;
};

http://www.dtcms.com/a/288133.html

相关文章:

  • 轻松学习C++:基本语法解析
  • JAVA高级第六章 输入和输出处理(一)
  • Git仓库使用
  • MacOS:如何利用终端来操作用户
  • 品鉴笔记:智利美人鱼磨坊甜红与甜白的风味对比
  • Java 大视界 -- 基于 Java 的大数据实时流处理在智能制造生产过程质量实时监控与异常诊断中的应用(352)
  • Linux 密码生成利器:pwgen 命令详解
  • Nestjs框架: 理解 RxJS响应式编程的核心概念与实践
  • C++中的虚继承
  • 思维链(CoT)技术全景:原理、实现与前沿应用深度解析
  • Edge浏览器设置网页自动翻译
  • 从随机数值到特征检测器的学习与更新
  • [硬件电路-37]:模拟电路、数字电路与计算软件信号处理的全方位比较
  • 暑假--作业3
  • 物联网系统中的可视化大屏定义
  • VSCode - VSCode 查找中文字符
  • 『 C++ 入门到放弃 』- AVL树
  • OpenCV 官翻 1 -介绍、安装、功能概览、核心操作
  • Streamlit 官翻 5 - 部署、社区云 Deploy
  • Linux内核空间的布局
  • 前端面试专栏-工程化:26.性能优化方案(加载优化、渲染优化)
  • 《Qt5串口开发》搭建跨平台通信系统
  • “外卖大战”正在改变国内“大零售”
  • 数据增强和微调
  • Codeforces Round 1037 (Div. 3)
  • windows docker-02-docker 最常用的命令汇总
  • uniapp props、$ref、$emit、$parent、$child、$on
  • 【数据结构】栈(stack)
  • xss-labs1-8题
  • ubuntu24 ros2 jazzy