C++编程优与Pascal的原因之一是C++中存在STL(标准模板库)。STL存在很多有用的方法。
C++模板库中的许多方法都需要相关参数有序,例如Sort()。显然,如果你想对一个集合进行排序,你必须要知道集合中的对象,那个在前那个在后。因此,学会如何定义比较方法是非常重要的。
C++模板库的许多容器需要相关类型有序,例如set<T> 和priority_queue<T>。
这篇文章旨在告诉大家如何为一个类定义一个排序方法,以便在STL容器或者方法中使用。 作为一个C++程序员,你应该知道这些方法。
如何定义排序?
简而言之,为一个类定义排序,我们就可以知道类的任意两个对象在排序的过程中谁在前谁在后。我们可以用一个方法来实现,这个方法返回一个bool值表示谁排在前面。显然,我们希望实现一个类似,f(x,y),这种形式的方法。它接收同一类型的对象作为两个参数,返回值则表明谁会出现在谁前面。
严格弱序化
几乎所有的方法或容器都需要排序来满足数学意义上的标准严格弱序化,否则这些方法或容器的行为将不可预知。
假设f(x,y)是一个比较函数。 如果该函数满足如下条件则它是严格弱序化的。
1.f(x,x) = false;
2. if f(x,y) then !f(y,x)
3.if f(x,y) and f(y,z) then f(x,z)
4. if !f(x,y)&&!f(y,x) then x==y; if x==y and y==z then x==z;
看上去有点晕乎,不过不用担心,只要你的比较方法能够满足对相等元素永远返回false,那你的方法就满足要求了。
三种实现方式:
1. 定义 < 操作符。
使用这种方法可以使我们自定义的类能够获得与生俱来的排序能力。例如,如果有如下类:
struct Edge { int from,to ,weight; };
因为要实现Kruskai算法,你希望图中的所有边依据权重按降序排列。 像这样来定义 operator<:
struct Edge { int from,to ,weight; bool operator <(Edge other) const { return weight>other.weight; } };
你定义的方法必须按照如下方法声明:
bool operator< (T other) const
注意: const关键字是必须的。
如果你不喜欢这种方式,比如,明明是要比较两个对象,方法却只有一个参数。你可以选择如下方式:
struct Edge { int from,to weight; friend bool operator<(Edge a,Edge b) { return a.weight>b.weight; } };
STL的pair<T1,T2>就具有与生俱来的排序能力。两个pair对象的比较这样的:先比较第一个参数,如果第一个参数相同再比较第二个参数。
所有内置类型都具有与生俱来的排序能力,这是由编译器赋予的。
2. 自定义排序方法。
使用这种方式常常用在如下情形:
a.比较内置类型
b.不能修改需要比较的类型
c.除了类型自定义的比较方式以外的比较方法
简单来说,一个比较方法接收两个同类型的对象作为参数并且返回一个bool值,原型如下:
bool name(T a,T b);
3. 重载()操作符
我们可以将比较函数作为STL容器构造函数的第一个参数,并且把函数类型作为模板参数。例如:
set<int,bool (*)(int,int)> s(cmp);
这样做或多或少会让人费解。那我们就来看看如何使用仿函数来消除你的疑惑吧。
我们需要定义一个新的类并重载()操作符。
vector<int> occurrences; struct cmp { bool operator()(int a, int b) { return occurrences[a] < occurrences[b]; } };
现在我们就可以把这个类作为模板参数传递给STL容器了。
set<int, cmp> s; priority_queue<int, vector<int>, cmp> pq;
STL也有一些内置的仿函数,例如less<T>,greater<T>等。
仿函数可以通过初始化然后像普通函数一样使用。最简单的就是在仿函数后面加上()。
sort(data.begin(), data.end(), greater<int>());
以上就是小编为大家带来的关于C++中定义比较函数的三种方法小结全部内容了,希望大家多多支持小牛知识库~
实际上,我正在通过其中一个教程,其中提到,当我们需要实现比较器接口时,我们可以覆盖equals方法(但是没有必要覆盖)。 所以,只是为了更好地理解 我重写了下面的方法 测验JAVA MyComparator.java 导入java。util。比较器; 对于其他场景 现在不管我从equals方法返回什么,不管是真是假。。它返回相同的树集值。如果有人能澄清equals方法的函数性的概念,请
本文向大家介绍Python3.x中自定义比较函数,包括了Python3.x中自定义比较函数的使用技巧和注意事项,需要的朋友参考一下 在Python3.x的世界里,cmp函数没有了。那么sorted,min,max等需要比较函数作为参数的函数该如何用呢? 以min函数的定义为例,有两种重载形式: 单参数(一个迭代器): 多参数(多个待比较内容): 本文主要讨论key=func参数的使用 。举例说明吧
本文向大家介绍MySQL中三种关联查询方式的简单比较,包括了MySQL中三种关联查询方式的简单比较的使用技巧和注意事项,需要的朋友参考一下 看看下面三个关联查询的 SQL 语句有何区别? 最大的不同更多是语法糖,但有一些有意思的东西值得关注。 为了方便区别,我们将前两种写法称作是 ANSI 风格,第三种称为 Theta 风格。 Theta 风格 在 FROM 短语中列出了关联的表名,而 WHE
本文向大家介绍C#比较时间大小的方法总结,包括了C#比较时间大小的方法总结的使用技巧和注意事项,需要的朋友参考一下 在编写程序,我们经常会对一些时间进行比较,比如要搜寻一个时间范围中的数据,需要用户输入开始时间和结束时间,如果结束时间小于或等于开始时间,那么程序是无法完成搜索的,所以在搜索前就需要对时间进行比较,确认结束时间大于开始时间。 下面小编举例说明C#中时间比较的方法。 1、打开Micro
我想了解Comparator类的comparing方法的定义。我会留下一些代码,以防它有助于解释。我正在使用一个名为Person的类,它基本上存储一个名字和一个姓氏。可以使用get方法检索此数据。 然后,我创建了一个人员列表: 我一直在测试不同的方法来对这个人员列表进行排序。在其他可能性中,我发现了这个: 我明白这些行的作用。基本上,此列表是使用比较器排序的,该比较器使用排序键(Person的名称