使用自定义比较器在c ++中声明priority_queue

时间:2013-04-19 18:33:32

标签: c++ std priority-queue

我正在尝试声明priority_queue of nodes,使用bool Compare(Node a, Node b)作为比较器函数(在节点类之外)。

我目前拥有的是:

priority_queue<Node, vector<Node>, Compare> openSet;

出于某种原因,我得到了Error: "Compare" is not a type name

将声明更改为priority_queue <Node, vector<Node>, bool Compare>

给了我Error: expected a '>'

我也试过了:

priority_queue<Node, vector<Node>, Compare()> openSet;
priority_queue<Node, vector<Node>, bool Compare()> openSet;
priority_queue<Node, vector<Node>, Compare<Node, Node>> openSet; 

我应该如何正确声明我的priority_queue

9 个答案:

答案 0 :(得分:69)

您应该为此声明一个类Compare并重载operator(),如下所示:

class Foo
{

};

class Compare
{
public:
    bool operator() (Foo, Foo)
    {
        return true;
    }
};

int main()
{
    std::priority_queue<Foo, std::vector<Foo>, Compare> pq;
    return 0;
}

或者,如果由于某些原因无法将其作为课程,您可以使用std::function

class Foo
{

};

bool Compare(Foo, Foo)
{
    return true;
}

int main()
{
    std::priority_queue<Foo, std::vector<Foo>, std::function<bool(Foo, Foo)>> pq(Compare);
    return 0;
}

答案 1 :(得分:13)

第三个模板参数必须是operator()(Node,Node)重载的类。 所以你必须这样创建一个类:

class ComparisonClass {
    bool operator() (Node, Node) {
        //comparison code here
    }
};

然后您将使用此类作为第三个模板参数,如下所示:

priority_queue<Node, vector<Node>, ComparisonClass> q;

答案 2 :(得分:11)

接受的答案会让您相信您必须使用班级或std::function作为比较器。这不是真的! cute_ptr's answer展示了如何将函数传递给构造函数,但有一种更简单的方法:

priority_queue<Node, vector<Node>, decltype(&Compare)> openSet(Compare);

也就是说,不需要显式编码函数的类型,你可以让编译器为你做这个。

答案 3 :(得分:5)

直接回答您的问题:

  

我尝试使用priority_queue声明bool Compare(Node a, Node b) as the comparator function个节点

     

我目前拥有的是:

priority_queue<Node, vector<Node>, Compare> openSet;
     

出于某种原因,我收到错误:

"Compare" is not a type name

编译器确切地告诉您错误:Compare不是类型名称,而是一个函数的实例,需要两个Nodes并返回bool
你需要的是指定函数指针类型:
std::priority_queue<Node, std::vector<Node>, bool (*)(Node, Node)> openSet(Compare)

答案 4 :(得分:4)

您必须先定义比较。有3种方法可以做到这一点:

  1. 使用课程
  2. 使用struct(与类相同)
  3. 使用lambda函数。

使用类/结构很容易,因为只需在执行代码上方编写这一行代码即可轻松声明

<html>
<body>
    <div id="first">
        <h1>make an account</h1>
        <form onsubmit="return false">
            new Name:<input id='nus' type="text" placeholder="Type your name here">
            new password:<input id='npass' type="password" placeholder="Type your password here">
            <button onclick="addaccount()" type="submit">add</button>
        </form>
    </div>
    <div id="scnd" style="display: none;">
        <p id='txt'></p>
        <form onsubmit="return false">
            Name:<input id='bar' type="text" placeholder="Type your name here">
            password:<input id='pass' type="password" placeholder="Type your password here">
            <button onclick="insert()" type="submit" id='insbtn'>insert</button>
        </form>
        <h1 id="acc" style="display: none;"> example for text <br>Lorem ipsum dolor sit amet consectetur,
            adipisicing elit. Magni ipsum voluptatibus quis eos laudantium commodi quae pariatur magnam in rem
            odio,
            neque officia tempora repellat ea soluta atque eius expedita!</h1>
    </div>
    <script>

        function addaccount() {
            var first = document.getElementById('first')
            const nus = document.getElementById('nus').value;
            const npass = document.getElementById('npass').value;
            localStorage.setItem('nus', nus)
            localStorage.setItem('npass', npass)
            first.style.display = 'none'
            scnd.style.display = 'block'
        }
        function insert() {

            var scnd = document.getElementById('scnd')
            var txt = document.getElementById('txt');
            var bar = document.getElementById('bar').value;
            var pass = document.getElementById('pass').value;
            var insbtn = document.getElementById('insbtn');
            var acc = document.getElementById('acc')
            localStorage.setItem('name', bar);
            localStorage.setItem('password', pass);

            var getus = localStorage.getItem('name')
            var getpass = localStorage.getItem('password');
            /*tried to set the username and password myself but i found it silly now i can't make more than a 
            user login and i can't go directly to signing in*/
            if (localStorage.getItem('nus') == bar && localStorage.getItem('npass') === pass) {
                acc.style.display = 'block';
                txt.innerHTML = 'hello' + ' ' + getus
            }
            else {
                txt.innerHTML = 'error not your account'
            }
        }
    </script>
</body>

</html>

呼叫代码:

struct compare{
  public:
  bool operator()(Node& a,Node& b) // overloading both operators 
  {
      return a.w < b.w: // if you want increasing order;(i.e increasing for minPQ)
      return a.w > b.w // if you want reverse of default order;(i.e decreasing for minPQ)
   }
};

答案 5 :(得分:2)

以防万一:

static bool myFunction(Node& p1, Node& p2) {}
priority_queue <Node, vector<Node>, function<bool(Node&, Node&)>> pq1(myFunction);

答案 6 :(得分:0)

也可以使用lambda函数。

auto Compare = [](Node &a, Node &b) { //compare };
std::priority_queue<Node, std::vector<Node>, decltype(Compare)> openset(Compare);

答案 7 :(得分:0)

首选结构,这就是std :: greater的作用

struct Compare {
  bool operator()(Node const&, Node &) {}
}

答案 8 :(得分:0)

使用最新的 c++ 标准,您实际上可以为比较器声明一个 lambda 函数,这将使代码更清晰。这是一个示例代码:

#include <queue>

class Foo
{
    public:
        int i;
};


int main()
{
    auto comparator = [](const Foo& a, const Foo& b) {
        return a.i > b.i;
    };

    std::priority_queue<Foo, std::vector<Foo>, decltype(comparator)>  pq(comparator);
    return 0;
}