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

问题记录——c++ sort 函数 和 严格弱序比较

引出

看下面这段cmp函数的定义


//按照vector第一个元素升序排序
static bool cmp(const vector<int>& a, const vector<int>& b){return a[0] < b[0];
}int eraseOverlapIntervals(vector<vector<int>>& intervals) {//按区间左端排序...sort(intervals.begin(), intervals.end(), cmp);...
}

问题

当我将比较函数中<换成<=时,会出现崩溃
在这里插入图片描述

原因

使用sort时需要遵循严格弱序,永远让等于的情况返回false

弱序定义

严格弱序比较指的是一种比较关系,具有以下性质:
反对称性:如果a小于b,那么b不可能小于a。但是a和b可以相等。
传递性:如果a小于b,并且b小于c,则a小于c。但是a和c可能相等。
反自反性:元素不能和自己比较。即a不小于a。

理解了一下,说人话就是:

反对称性:如果[a,b]满足你定义的规则(return了true),那么[b,a]就一定是不满足规则的,否则就得return false。
传递性:如果[a,b]满足规则,[b,c]满足规则,则[a,c]也一定满足规则。
反自反性:元素不能和自己比较。即[a,a]是不满足规则的。

显然,如果a=b时返回true的话,不满足反对称性反自反性

更进一步

看一部分c++sort原码

template<typename _RandomAccessIterator, typename _Compare>
void __sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) {... while (__first != __last && __comp(*__first, __pivot)) ++__first;...
}

sort是用快排实现的,

在这段代码中,

__comp(*__first, __pivot) 

这个表达式的结果,决定了while循环是否继续进行,
如果这个表达式的结果为 true,那么 __first 就会向右移动,直到找到一个元素不再小于 __pivot。

a.如果表达式返回 true,那么意味着 __first 小于 __pivot,应该被放到左边分区;
b.如果返回 false,则意味着 __first 大于或等于__pivot,应该被放到右边分区
所以如果元素相等,那么 __comp(
__first, __pivot) 应该返回 false。

而stl判断相等是使用的 !Cmp(a,b) && !Cmp(b,a),cmp是你自己定义的函数,
如果cmp在a,b相等时返回true,那么在a,b相等时表达式可以简化成 !true && !true = false
最后,导致了输入两个相等的元素,在stl看来这两个元素既不是小于,也不是等于,也不是大于。

好了,最终会导致什么后果呢?(先去大概看下快排代码)
在从小到大遍历时(pivot左边),判断小于,相等的元素返回的是false,被扔到了右边,
右边判断相等时(pivot右边),返回也是false,又被扔了回来,
循环往复,以至无穷,最终导致程序崩溃。

结论

自定义sort的cmp时, 永远让等于的情况返回false!!!

http://www.lryc.cn/news/301224.html

相关文章:

  • 《Go 简易速速上手小册》第9章:数据库交互(2024 最新版)
  • redis的hash数据结构底层简记
  • 清除Django的管理员admin站点中“Recent Actions“最近活动面板上的所有信息
  • 【JVM篇】ThreadLocal中为什么要使用弱引用
  • Stable Diffusion教程——stable diffusion基础原理详解与安装秋叶整合包进行出图测试
  • 【JavaEE】_线程与多线程的创建
  • 【前端工程化面试题】如何优化提高 webpack 的构建速度
  • 免费chatgpt使用
  • OpenCV识别人脸案例实战
  • VOSK——离线语音库
  • ELAdmin 隐藏添加编辑按钮
  • 浅谈Websocket
  • JavaScript闭包详细介绍
  • pytorch神经网络入门代码
  • 代码随想录算法训练营第三十四天|860.柠檬水找零 406.根据身高重建队列 452. 用最少数量的箭引爆气球
  • Ditto:提升剪贴板体验的宝藏软件(复制粘贴效率翻倍、文本处理好助手)
  • 【自然语言处理-工具篇】spaCy<2>--模型的使用
  • Java之通过Jsch库连接Linux实现文件传输
  • Nginx七层负载均衡之动静分离
  • 305_C++_定义了一个定时器池 TimerPool 类和相关的枚举类型和结构体
  • 大整数因数分解工具——yafu
  • 非关系型数据库(NOSQL)和关系型数据库(SQL)区别详解
  • 7.Cloud-GateWay
  • 【Linux】Framebuffer 应用
  • markdown绘制流程图相关代码片段记录
  • 云计算基础-计算虚拟化-CPU虚拟化
  • MySQL数据库⑪_C/C++连接MySQL_发送请求
  • 选择排序和快速排序(1)
  • 得物面试:Redis用哈希槽,而不是一致性哈希,为什么?
  • matlab发送串口数据,并进行串口数据头的添加,我们来看下pwm解析后并通过串口输出的效果