众所周知,balabalabalabala············。

所以掌握sort函数(库文件:)的用法还是很有必要的。

一般选手只会简单地用用sort排一排数组之类,但是一旦掌握了sort的精髓cmp函数(也有叫comp,名字不重要)的重构,sort函数也可以玩得出神入化。

这里只是不全面地记录下了在切题的过程中遇到的重构cmp的应用,仅供参考:

一、cmp函数的原理探究

研究sort的底层代码就会知道,sort函数非常强大,内部结合了多种排序算法以达到相对稳定的高效。但是不管排序的策略如何,其中都用一个“比较”的步骤。而cmp函数(全称大概代表了单词compare,表示“比较”的意思)便定义了这个比较的标准。

举个栗子:当比较一个数组中a、b(a

怎么把我们对cmp函数的重构应用到sort函数里面呢?

从下面可以看出sort模板有三个参数:

voidsort ( RandomAccessIterator first, RandomAccessIterator last );void sort (RandomAccessIterator first, RandomAccessIterator last, Compare comp);//排序区间为[first,last)//注: 随机迭代器,能用此算法的容器是支持随机访问的容器:vector, deque, string。不支持链表一类的排序。

然后我们转到sort的定义找到默认的comp:

//TEMPLATE FUNCTION sort

templateinlinevoidsort(_RanIt _First, _RanIt _Last)

{//order [_First, _Last), using operator<

_STD sort(_First, _Last, less<>());

}

是 less<>(),然后继续转到这个的定义去看:

//TEMPLATE STRUCT less

template

structless

:public binary_function<_ty _ty bool>{//functor for operator<

bool operator()(const _Ty& _Left, const _Ty& _Right) const{//apply operator< to operands

return (_Left <_right>

}

};

好吧实际上就是个——小于号。

也就是说,比较两个元素a,b的时候,a=b则comp函数返回false;由默认排序为升序我们可以推知,comp为true的时候a,b顺序不变,!comp为true的时候a,b顺序改变。(只是暂时的推理!!后面发现有坑!!)

为了方便记忆和使用,我们可以这么想:记相对位置分别在左边和右边的两个元素(这里不用a和b表示)为left和right,排序后的left和right的关系是使comp返回true的关系。(但要注意一个特殊情况,left = right的时候comp返回都是false,按照排序的原理比较这两个元素的时候会交换他们的位置,不过交换前后整个数组并无差别,不过这两个元素只会比较一次,所以也不会无限交换下去(后来事实证明我的想法是错误的))

然而事实真的是这样吗?

这时候我写了一个cmp:

1 bool cmp(int left,intright)2 {3 return left >=right;4 }

当在排序的数组中有两个相同的元素的时候,编译器报了错:

于是我就去查了一下问题的原因,然后知道了sort没有我想的那么简单。

什么是严格弱序?

C++关联容器的有序容器对元素关键字的类型有要求,元素关键字的类型必须定义了严格弱序(stick weak ordering)

拿内置类型来说,C++都定义了 “

严格弱序有什么用?

对于内置类型我们自然可以有、=来判断两个值的大小关系,而对于自定义的类类型,为它定义三种比较操作符是没有必要的,只用一个严格弱序(这里就用

a小于b

a < b

b小于a

b < a

a等于b

!(a < b) && !( b < a )

严格弱序的三条要求

两个关键字不能同时“严格弱序”于对方

如果a“严格弱序”于b,且b“严格弱序”于c,则a必须“严格弱序”于c

如果存在两个关键字,任何一个都不“严格弱序”于另一个,则这两个关键字是相等的。

如果我们把

1.两个关键字不能同时“<=”于对方

显然有a<=b,b<=a,a,b相等时成立

2.如果存在两个关键字,任何一个都不“<=”于另一个,则这两个关键字是相等的。

a不小于等于b,且b也不小于等于a,也就是a>b且b>a,这明显是一个伪命题

然后是报错的原因以及解决办法,参考:

而有时,我们所比较的元素并不仅仅是一个值,还可以是一个结构,一个类的实例,或者排序的策略并不想要升序,这时候就要我们自己重构一下cmp函数了。

二、应用

1、非升序排序(int)

#include #include

using namespacestd;bool cmp(int left,intright)

{return left >right;

}intmain()

{int a[7] = { 9, 8, -7, -6, 5, 4,4};

sort(a, a+ 7,cmp);for (int i = 0; i < 7; ++i)

{

cout<

}

system("pause");return 0;

}

2.结构体排序(多级排序)

#include#include

using namespacestd;structnode{inta;intb;

}nodes[5] = { {1,20}, {5,4}, {5,6}, {7,8}, {5,6} };bool cmp(const node left,const node right)//排序规则:按a 从大到小,若a相等,则按b从大到小

{if (left.a ==right.a)

{return left.b >right.b;

}else{return left.a >right.a;

}

}intmain()

{

sort(nodes, nodes+ 5, cmp);for (int i = 0; i < 5; ++i)

{

cout<< "第" << i + 1 << "个:" << nodes[i].a << "," << nodes[i].b<

}

system("pause");return 0;

}

3.类实例排序(和同结构体差不多就不写了)

·····························

未完待续,遇到有意思的我会再加上去

c语言cmp函数含义,【C艹】关于sort用法之重构cmp(comp)函数的笔记相关推荐

  1. 代码重构(一):函数重构规则

    [笔记] 以下是通用的代码重构规则 python代码重构技巧看这里:Python重构代码的一些模式 ========================== 重构是项目做到 一定程度后必然要做的事情.代码 ...

  2. Android JNI编程(三)——C语言指针的初步认识、指针变量、互换两个数、函数返回多个值...

    版权声明:本文出自阿钟的博客,转载请注明出处:http://blog.csdn.net/a_zhon/. 目录(?)[+] 一.什么是指针? 简单来说: 指针就是内存地址      内存地址就是指针. ...

  3. java语言中的标识符_Java语言基本语法(一)————关键字标识符(Java语言标识符命名规范Java语言的包名、类名、接口名、变量名、函数名、常量名命名规则 )...

    一.关键字 关键字的定义和特点 定义:被Java语言赋予特殊含义,用做专门用途的字符串(单词). 特点:关键字中所有字母均为小写 下面列举一些常用的关键字. 用于定义数据类型的关键字:byte.sho ...

  4. 聊一聊C语言变量的含义

    欢迎点击「算法与编程之美」↑关注我们! 本文首发于微信公众号:"算法与编程之美",欢迎关注,及时了解更多此系列文章. 我们知道每一个程序的运行都需要内存,那么C语言的变量的定义是什 ...

  5. SHELL/SSH基础知识(入门篇)-包含 shell 脚本语言的基本用法、 shell 脚本语言的基本用法、流程控制、函数 function、其它脚本相关工具、数组 array(欢迎留言交流)

    目录 1 shell 脚本语言的基本用法 1.1 shell 脚本注释规范 1.1.1 shell 脚本注释规范 1.1.2 执行(5种) 1.1.3 在远程主机运行本地脚本 1.1.4 检查shel ...

  6. c语言符号txt下载,c语言中符号含义.txt

    c语言中符号含义.txt char 壺 壨 char ; char 壻 char a; char asd; char xa; float 壺 壨 float ; float 壻 float a; fl ...

  7. R语言计算杰卡德相似系数(Jaccard Similarity)实战:自定义函数计算Jaccard相似度、对字符串向量计算Jaccard相似度、将Jaccard相似度转化为Jaccard距离

    R语言计算杰卡德相似系数(Jaccard Similarity)实战:自定义函数计算Jaccard相似度.对字符串向量计算Jaccard相似度.将Jaccard相似度转化为Jaccard距离 目录 R ...

  8. R语言广义线性模型函数GLM、R中有几种logistic回归扩展和变异、robust包中的glmRob函数鲁棒logistic回归、ms包中的lrm函数拟合序数逻辑回归

    R语言广义线性模型函数GLM.glm函数构建逻辑回归模型(Logistic regression).R中有几种logistic回归扩展和变异.robust包中的glmRob函数鲁棒logistic回归 ...

  9. R语言使用haven包的read_spss函数读取spss格式数据、使用haven包的read_sas函数读取SAS格式数据、使用haven包的read_dta函数读取Stata格式数据

    R语言使用haven包的read_spss函数读取spss格式数据.使用haven包的read_sas函数读取SAS格式数据.使用haven包的read_dta函数读取Stata格式数据 目录

  10. R语言pacman包管理R编程语言需要的包实战:使用p_load函数安装和加载多个R包、使用p_unload函数卸载多个R包、使用p_update函数更新过期的R包

    R语言pacman包管理R编程语言需要的包实战:使用p_load函数安装和加载多个R包.使用p_unload函数卸载多个R包.使用p_update函数更新过期的R包 目录

最新文章

  1. 简历受HR欢迎的四大特点
  2. js 正则表达式奇偶字符串替换_Python中的正则表达式及其常用匹配函数用法简介...
  3. BOOST_PROTO_DEFINE_OPERATORS宏使用 std::vector<> 和 std::list 非原型类型来原型化表达式的示例
  4. 讲述华为发布鸿蒙系统,华为鸿蒙系统正式版首批升级名单公布:这8款机型用户有福了!...
  5. Lamp安装与实现动态网页案例(一)
  6. java基础之XML
  7. 【译】在 Linux 上不安装 Mono 构建 .NET Framework 类库
  8. asp 文本转时间_三分钟学会在ASP.NET Core MVC 中使用Cookie
  9. 解决ubuntu未安装无线网卡驱动的问题
  10. 零窗口探测怎么抓包_天问·探路火星|五大亮点!最快“胖五”把探测器送入苍穹...
  11. zabbix监控Linux系统服务
  12. IOS开发之----四舍五入问题
  13. [2019杭电多校第十场][hdu6701]Make Rounddog Happy
  14. asp.net回调javascript
  15. 静态路由配置《计算机网络》实验六,思科路由器静态路由配置实验案例详解
  16. 97、锐捷交换机常用配置命令汇总
  17. 【云和恩墨大讲堂】视频课程震撼来袭-SQL优化精选案例
  18. 表格里加横线一分为二_excel表格分割线一分为二斜线
  19. GNSS定位中的不同高度概念及计算
  20. bandizip修改压缩文件内容_Bandizip: 压缩和解压缩

热门文章

  1. 【风光摄影】用滤镜在前期控制完美光比
  2. 免费外链资源列表汇总
  3. JVM报错GC overhead limit exceeded
  4. 模拟信道和数字信道的区别
  5. 面向对象版学员管理系统 Python
  6. 我国期货市场发展潜力和方向
  7. STM32使用大彩串口屏程序框架使用总结
  8. iptables匹配statistic
  9. substring用法,between...and用法 trim标签的用法 模糊查询
  10. 搭建V2P及中青看点教程