• 优先级队列priority_queue自定义比较函数


    1.自定义数据类型时

    https://blog.csdn.net/HermitSun/article/details/107101944

     参照378. 有序矩阵中第 K 小的元素

    class Point
    {
        int val, x, y;
        Point(int val, int x, int y) : val(val), x(x), y(y) {}
        bool operator>(const Point &p) const { return val > p.val; }
    };

    自定义 定义一个小顶堆,这里的greater运算符函数,参数需要是const,并且需要时const函数,不然会报错:

    this‘ argument has type ‘const xxx‘, but method is not marked const

     初始化时:

    priority_queue<Point, vector<Point>, greater<Point>> q;

      q.emplace(1, 1, 1);

    greater函数的文档:

    也就是说在堆排序时,调用greater,greater的参数是const的,并且是const成员函数,在内部比较时会用到上面重写的operator>函数,而const成员函数不能调用非const成员函数,所以会报错,所以需要将其声明为const函数,另外如果operator>的参数列表不声明为const,但operator中为const会导致形参无法赋值。

    2.三种方法

    https://www.cnblogs.com/Harley-Quinn/p/6104306.html

    2.1函数指针

    bool greaterInt(const int& lhs, const int& rhs)
    {
        return lhs > rhs;
    }
    priority_queue<int, vector<int>, bool(*)(const int&, const int&)> q(greaterInt);

    但这样写其实是写的复杂了,C风格的,不常用。

     2.2函数对象

    仿函数类

    template <typename T>
    struct Greater
    {
        bool operator()(const T& lhs, const T& rhs) const
        {
            return lhs > rhs;
        }
    };
    priority_queue<int, vector<int>, Greater<int>> q;

    采用显式写法:

    priority_queue<int, vector<int>, Greater<int>> q(Greater<int>());

    即显式地调用Greater类的默认构造函数,但这样会报错,所以不要这样。

    2.3 lamda表达式

        auto comp = [](const int& lhs, const int& rhs) { return lhs > rhs; };
        priority_queue<int, vector<int>, decltype(comp)> q(comp);

    官方文档中给出的具体的例子,https://en.cppreference.com/w/cpp/container/priority_queue/priority_queue:

    #include <iostream>
    #include <queue>
    #include <vector>
    #include <utility>
     
    using my_pair_t = std::pair<size_t,bool>;
     
    using my_container_t = std::vector<my_pair_t>;
     
    int main()
    {
        auto my_comp =
            [](const my_pair_t& e1, const my_pair_t& e2) 
            { return e1.first > e2.first; };
        std::priority_queue<my_pair_t,
                            my_container_t,
                            decltype(my_comp)> queue(my_comp);
        queue.push(std::make_pair(5, true));
        ....
    }

    但是结合第一节中的讨论,如果存储的类型是指针类型,那么参数就不能是const的,有两个具体的举例:

    23. 合并K个升序链表

            auto cmp=[](const ListNode* & a,const ListNode* & b){return a->val>b->val;};//不能用const,是错的!OMG
            priority_queue<ListNode*,vector<ListNode*>,decltype(cmp)> pq(cmp);

    注意,定义的cmp参数类型是指针类型,并且是const的,提交会报错:

     本人手动尝试了基本类型的指针:

        auto comp = [](const int*& lhs, const int*& rhs) { return *lhs > *rhs; };
        priority_queue<int*, vector<int*>, decltype(comp)> q(comp);
        int* a=new int(5);
        int *b=new int(6);
        q.push(a);
        q.push(b);

    会报错:

    error: cannot bind non-const lvalue reference of type 'const int*&' to an rvalue of type 'const int*'

    搜索相关的结果都是  临时变量不能用作非const引用。所以这个错误的原因未知。

    总的修改之后:

            auto cmp=[](ListNode*& a, ListNode*& b){return a->val>b->val;};
            priority_queue<ListNode*,vector<ListNode*>,decltype(cmp)> pq(cmp);

    ok.

        auto comp = [](int* & lhs, int* & rhs) { return *lhs > *rhs; };
        priority_queue<int*, vector<int*>, decltype(comp)> q(comp);
        int* a=new int(5);
        int *b=new int(6);
        q.push(a);
        q.push(b);

    ok.

    所以如果T是指针类型,那么函数形参中不加const。

  • 相关阅读:
    source insight 使用介绍
    android 自定义progressBar
    appium环境安装
    js定义类的三种方法
    对象,函数,构造函数this,原型
    mindjet使用技巧
    在wamp下安装bugfree
    QTP
    powerdesigner使用
    随笔
  • 原文地址:https://www.cnblogs.com/BlueBlueSea/p/14855293.html
Copyright © 2020-2023  润新知