C++学习笔记3:sort和priority_queue的比较器重载

news/2024/6/30 8:22:34

1 sort

三种方法

1. 直接重载函数

#include <vector>
#include <memory>
#include <vector>
#include <queue>
#include <iostream>
#include <algorithm>

using namespace std;

class Node{
public:
    int value;
    Node(){value = 0;};
    explicit Node(int value){
        this->value = value;
    }
};

bool cmp(const Node& n1, const Node& n2){
    return n1.value > n2.value;
}

int main(){
    Node* a = new Node[5];
    a[0].value = 2;
    a[1].value = 5;
    a[2].value = 2;
    a[3].value = 9;
    a[4].value = 0;

    sort(a, a + 5, cmp);
    for(int i = 0; i < 5; i++) cout << a[i].value << " ";
    return 0;
}

2. 在类中时,需要注意加上static,因为非静态函数不加static指针的时候,会隐藏地传一个this指针,导致参数表不符

#include <vector>
#include <memory>
#include <vector>
#include <queue>
#include <iostream>
#include <algorithm>

using namespace std;

class Node{
public:
    int value;
    Node(){value = 0;};
    explicit Node(int value){
        this->value = value;
    }

    static bool cmp(const Node& n1, const Node& n2){
        return n1.value > n2.value;
    }

    static void fun(){
        Node* a = new Node[5];
        a[0].value = 2;
        a[1].value = 5;
        a[2].value = 2;
        a[3].value = 9;
        a[4].value = 0;

        sort(a, a + 5, cmp);
        for(int i = 0; i < 5; i++) cout << a[i].value << " ";
    }
};

int main(){
    Node::fun();
    return 0;
}

3. 定义一个类,重载()运算符

#include <vector>
#include <memory>
#include <vector>
#include <queue>
#include <iostream>
#include <algorithm>

using namespace std;

class Node{
public:
    int value;
    Node(){value = 0;};
    explicit Node(int value){
        this->value = value;
    }
};

class CMP{
public:
    bool operator()(const Node& n1, const Node& n2){
        return n1.value > n2.value;
    }
};


int main(){
    Node* a = new Node[5];
    a[0].value = 2;
    a[1].value = 5;
    a[2].value = 2;
    a[3].value = 9;
    a[4].value = 0;

    sort(a, a + 5, CMP());
    for(int i = 0; i < 5; i++) cout << a[i].value << " ";
    return 0;
}

2 priority_queue

需要注意的是,priority_queue是一个对象模板,而sort是一个函数模板,因此在重载的时候有些区别。

sort较为常用的参数表是:

first和last是迭代器,而comp是比较器,实现方式有上面的三种。

对于priority_queue,首先需要往确定模板的类型,然后给构造函数传递参数。

上面这段是用实际类型将类模板priority_queue实例化为模板类,还并没有到由模板类构造对象的那一步。此处compare需要传递的是比较器的类型,而不是比较器本身。

我们再看构造函数:

这个地方需要传递的才是比较器。所以当比较器为函数的时候,我们的写法是:

priority_queue<Node, vector<Node>, decltype(&cmp)> pq(cmp);

 前面的decltype(&cmp)是比较器的类型,后面的cmp给构造函数传递比较器。

那么问题来了,cmp的类型为什么不是decltype(cmp)而是decltype(&cmp)呢?

cmp是一个函数指针,代表着函数的首地址,类型是:bool (*)(::Node &,::Node &),即decltype(&cmp),而查文档可知,decltype(函数)返回的是这个函数的返回值类型,即decltype(cmp)为bool (::Node &,::Node &)。

接下来是三种写法具体实现

1. 直接用函数

#include <vector>
#include <memory>
#include <vector>
#include <queue>
#include <iostream>

using namespace std;

class Node{
public:
    int value;
    Node(){value = 0;};
    explicit Node(int value){
        this->value = value;
    }
};

bool cmp(const Node& n1, const Node& n2){
    return n1.value > n2.value;
}

int main(){
    Node* a = new Node[5];
    a[0].value = 2;
    a[1].value = 5;
    a[2].value = 2;
    a[3].value = 9;
    a[4].value = 0;

    priority_queue<Node, vector<Node>, decltype(&cmp)> pq(cmp);
    pq.push(a[0]);
    cout << pq.top().value << endl;
    pq.push(a[1]);
    cout << pq.top().value << endl;
    pq.push(a[2]);
    cout << pq.top().value << endl;
    pq.push(a[3]);
    cout << pq.top().value << endl;
    pq.push(a[4]);
    cout << pq.top().value << endl;
    return 0;
}

2. 类中函数加static

#include <vector>
#include <memory>
#include <vector>
#include <queue>
#include <iostream>

using namespace std;

class Node{
public:
    int value;
    Node(){value = 0;};
    explicit Node(int value){
        this->value = value;
    }

    static bool cmp(const Node& n1, const Node& n2){
        return n1.value > n2.value;
    }

    static void fun(){
        Node* a = new Node[5];
        a[0].value = 2;
        a[1].value = 5;
        a[2].value = 2;
        a[3].value = 9;
        a[4].value = 0;

        priority_queue<Node, vector<Node>, decltype(&cmp)> pq(cmp);
        pq.push(a[0]);
        cout << pq.top().value << endl;
        pq.push(a[1]);
        cout << pq.top().value << endl;
        pq.push(a[2]);
        cout << pq.top().value << endl;
        pq.push(a[3]);
        cout << pq.top().value << endl;
        pq.push(a[4]);
        cout << pq.top().value << endl;
    }
};

int main(){
    Node::fun();
    return 0;
}

3. 比较类,重载()运算符

#include <vector>
#include <memory>
#include <vector>
#include <queue>
#include <iostream>

using namespace std;

class Node{
public:
    int value;
    Node(){value = 0;};
    explicit Node(int value){
        this->value = value;
    }
};

class CMP{
public:
    bool operator()(const Node& n1, const Node& n2){
        return n1.value > n2.value;
    }
};

int main(){
    Node* a = new Node[5];
    a[0].value = 2;
    a[1].value = 5;
    a[2].value = 2;
    a[3].value = 9;
    a[4].value = 0;

    // CMP cmp;
    // priority_queue<Node, vector<Node>, CMP> pq(cmp);

    priority_queue<Node, vector<Node>, CMP> pq;
    pq.push(a[0]);
    cout << pq.top().value << endl;
    pq.push(a[1]);
    cout << pq.top().value << endl;
    pq.push(a[2]);
    cout << pq.top().value << endl;
    pq.push(a[3]);
    cout << pq.top().value << endl;
    pq.push(a[4]);
    cout << pq.top().value << endl;
    return 0;
}


http://lihuaxi.xjx100.cn/news/1178919.html

相关文章

深入理解深度学习——正则化(Regularization):半监督学习

分类目录&#xff1a;《深入理解深度学习》总目录 在半监督学习的框架下&#xff0c; P ( x ) P(x) P(x)产生的未标记样本和 P ( x , y ) P(x, y) P(x,y)中的标记样本都用于估计 P ( y ∣ x ) P(y | x) P(y∣x)或者根据 x x x预测 y y y。在深度学习的背景下&#xff0c;半监督…

Pyhive——介绍使用举例

介绍 PyHive 是一个 Python 数据库连接工具和 ORM 框架&#xff0c;它提供了一个 Python 接口让用户可以连接多个不同的 Hadoop 数据存储系统&#xff0c;包括 Apache Hive, Apache Impala, Amazon Athena, Apache Spark SQL 等等。 PyHive 的目标是让 Python 开发者能够方便…

关于f-stack转发框架的几点分析思考

使用DPDK收包&#xff0c;想要用到TCP协议栈&#xff0c;可选的方案有linux原生的tun/tap口以及DPDK自带的KNI驱动&#xff0c;这两种都是通过将DPDK收到的报文注入到linux内核来使用TCP协议栈的功能&#xff0c;然后&#xff0c;用户态协议栈可以考虑开源的f-stack&#xff0c…

c# cad二次开发通过获取excel数据 在CAD绘图,将CAD属性导出到excel

c# cad二次开发通过获取excel数据 在CAD绘图&#xff0c;将CAD属性导出到excel using Autodesk.AutoCAD.ApplicationServices; using Autodesk.AutoCAD.EditorInput; using Autodesk.AutoCAD.Runtime; using System; using System.Collections.Generic; using System.Linq; us…

你在项目中是如何使用kafka的?

消息中间件是现代分布式系统中不可或缺的组件之一&#xff0c;它提供了高可靠性、高吞吐量的消息传递机制。Kafka作为一种开源的分布式消息队列系统&#xff0c;广泛应用于各行各业。本篇博客将介绍在实践中使用Kafka的一些技巧和最佳实践&#xff0c;帮助开发人员更好地利用Ka…

如何在华为OD机试中获得满分?Java实现【表示数字】一文详解!

✅创作者&#xff1a;陈书予 &#x1f389;个人主页&#xff1a;陈书予的个人主页 &#x1f341;陈书予的个人社区&#xff0c;欢迎你的加入: 陈书予的社区 &#x1f31f;专栏地址: Java华为OD机试真题&#xff08;2022&2023) 文章目录 1. 题目描述2. 输入描述3. 输出描述…

[元带你学: eMMC协议详解 10] Device 识别流程 与 中断模式

依JEDEC eMMC 5.1及经验辛苦整理&#xff0c;付费内容&#xff0c;禁止转载。 所在专栏 《元带你学: eMMC协议详解》 全文2700字&#xff0c;重点需掌握设备识别过程&#xff08;CMD1 -> CMD2 -> CMD3&#xff09;, 这很常用&#xff0c; 也是最容易出现异常的地方。其他…

Linux(基础IO详解)

在基础IO这篇博客中&#xff0c;我们将了解到文件系统的构成&#xff0c;以及缓冲区究竟是个什么东东&#xff0c;我们都知道缓冲区&#xff0c;有时也谈论缓冲区&#xff0c;但不一定真的去深入了解过缓冲区。为什么内存和磁盘交互速度如此之慢&#xff1f;为什么都说Linux中一…