sort函数的自定义比较方式

1. 重载"<"运算符

第一种:写在struct或class的内部。下面是一个例子:

class Node {
public:
	int x_, y_;
	Node(int x, int y) :x_(x), y_(y) {}
	
	//重载"<"运算符(写在类内部)
	bool operator<(const Node& a)const { // 返回true,表示this的优先级小于a
		// x大的排在前面;x相同时,y大的排在前面
		if (x_ == a.x_) {
			return y_ > a.y_;
		}
		return x_ > a.x_;
	}
};

int main() {
	// 待排序数组
	vector<Node> vec{ Node(10,20),Node(20,10),Node(10,10) };
	
	sort(vec.begin(), vec.end());// 重载"<"运算符
}

写在内部的就需要注意两个const。因为运算符<的重载可以看作node_b.operator<(node_a)priority_queue在对元素进行比较的时候,两个元素都是const类型的。因此,运算符<的重载必须能满足两个const类型的元素进行比较。我们来看,第一个const,即const Node a表示的是node_a必须为const;第二个const,即函数声明之后的那个const,表示的是运算符<可以被const类型的node_b调用。有了这两个const,才能满足两个const类型的元素进行比较。

第二种:写在struct或class的外部。

class Node {
public:
	int x_, y_;
	Node(int x, int y) :x_(x), y_(y) {}
}

// 重载"<"运算符(写在类外部)
bool operator<(Node& a, Node& b) { // 返回true,表示this的优先级小于a
	// x大的排在前面;x相同时,y大的排在前面
	if (a._x == b._x) {
		return a._y > b._y;
	}
	return a._x > b._x;
}

int main() {
	// 待排序数组
	vector<Node> vec{ Node(10,20),Node(20,10),Node(10,10) };
	
	sort(vec.begin(), vec.end());// 排序
}

2. 重写函数对象(仿函数)

函数对象也叫做仿函数,《STL源码剖析》中是这么解释的:“函数对象是一种具有函数特质的对象”。函数对象是一个广泛的概念,所有具有函数行为的对象都可以称为函数对象。所谓的函数行为是指的是可以使用()调用并传递参数。广义上来讲,lambda表达式也是一个函数对象。但是在这里,我们所讲的是一种特殊的函数对象,这种函数对象实际上是一个结构体或类的实例,只不过这个结构体或类重载了函数调用符"()"。STL里有自己的仿函数,greater()和less(),我们这里要做的就是重写一个仿函数来代替它们。函数对象的重写也有两种写法:一种是写在自定义结构体的内部,另一种是写在自定义结构体的外部。值得一说的是,使用这种方法,函数签名末尾的const修饰可有可无。这是因为末尾的const代表了不会修改结构体内部变量的值,这和我们要用到的功能毫无关系,因此可以忽略。

第一种:写在类内部:

class Node {
public:
	int x_, y_;
	Node(int x, int y) :x_(x), y_(y) {}
	
	// 重写仿函数(写在类内部)
	bool operator()(Node& a, Node& b) const { // 返回true,表示this的优先级小于a
	// x大的排在前面;x相同时,y大的排在前面
		if (a._x == b._x) {
			return a._y > b._y;
		} 
		return a._x > b._x;
	}
}

int main() {
	// 待排序数组
	vector<Node> vec{ Node(10,20),Node(20,10),Node(10,10) };
	
	sort(vec.begin(), vec.end(), Node()); // 排序
}

第二种:写在类外部

class Node {
public:
    int x_, y_;
    Node(int x, int y) :x_(x), y_(y) {}
};

// 重写仿函数(写在类外部)
class cmp {
public:
bool operator()(Node a, Node b) { // 返回true,表示this的优先级小于a
    // x大的排在前面;x相同时,y大的排在前面
    if (a.x_ == b.x_) {
        return a.y_ > b.y_;
    }
    return a.x_ > b.x_;
}
};

int main() {
	// 待排序数组
	vector<Node> vec{ Node(10,20),Node(20,10),Node(10,10) };

	sort(vec.begin(), vec.end(), cmp()); // 排序
}

3. 函数指针

函数指针:通过编写一个外部的比较函数,实现 < 方法,然后将函数指针传入。

class Node {
public:
	int x_, y_;
	Node(int x, int y) :x_(x), y_(y) {}
}

// 3.函数指针
bool cmp1(Node& a, Node& b) { // 返回true,表示this的优先级小于a
	// x大的排在前面;x相同时,y大的排在前面
	if (a._x == b._x) {
		return a._y > b._y;
	}
	return a._x > b._x;
}

int main() {
	// 待排序数组
	vector<Node> vec{ Node(10,20),Node(20,10),Node(10,10) };
	
	sort(vec.begin(), vec.end(), cmp1); // 排序
}

4. lambda表达式

对于sort(),可以直接使用lambda表达式代替仿函数。

class Node {	
public:
	int x_, y_;
	Node(int x, int y) :x_(x), y_(y) {}
}

// 4.lambda表达式
auto cmp2 = [](Node& a, Node& b) {return a._x == b._x ? a._y > b._y :a._x > b._x; };

int main() {
	// 待排序数组
	vector<Node> vec{ Node(10,20),Node(20,10),Node(10,10) };
	
	sort(vec.begin(), vec.end(), cmp2); // 排序
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

呆先森HIT

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值