簡體   English   中英

使用自定義比較器在 C++ 中聲明 priority_queue

[英]declaring a priority_queue in c++ with a custom comparator

我正在嘗試聲明一個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

注意 - 您可能還想查看其他答案,尤其是帶有 decltype 和 lambda 的答案


您應該像這樣聲明一個類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;
}

接受的答案顯示了如何使用類或std::function作為比較器。 我們也可以傳遞一個函數指針,正如cute_ptr's answer已經顯示的那樣。 但是,這樣做的語法比那里顯示的要簡單得多:

class Node;
bool Compare(Node a, Node b);

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

也就是說,不需要顯式編碼函數的類型,您可以讓編譯器使用decltype為您執行此操作。

如果比較器是 lambda,這將非常有用。 除了使用decltype之外,您不能以任何其他方式指定 lambda 的類型。 例如:

auto compare = [](Node a, Node b) { return a.foo < b.foo; }
std::priority_queue<Node, std::vector<Node>, decltype(compare)> openSet(compare);

第三個模板參數必須是重載了operator()(Node,Node)的類。 所以你必須以這種方式創建一個類:

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

然后您將使用此類作為第三個模板參數,如下所示:

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

直接回答你的問題:

我正在嘗試聲明一個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)

您必須先定義比較。 有 3 種方法可以做到這一點:

  1. 使用類
  2. 使用結構(與類相同)
  3. 使用 lambda 函數。

使用類/結構很容易,因為很容易聲明,只需在執行代碼上方寫下這行代碼

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)
   }
};

調用代碼:

priority_queue<Node,vector<Node>,compare> pq;

也可以使用 lambda 函數。

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

如果這對任何人都有幫助:

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

在優先級隊列中,有一個預定義的布爾函數“operator<()”,請嘗試根據您的要求重載該函數。

bool operator<(const Node& x,const Node& y){
    return x.data>y.data;
}

priority_queue<Node> min_heap;

使用最新的 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;
}

更喜歡 struct,這就是 std::greater 所做的

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

struct的幫助下,我們也可以做到這一點。 代碼將如下所示。

struct myCompare{
    bool operator()(Node &a, Node &b){
        // Your own custom logic to compare the two nodes and return a boolean value.
    }
}

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM