c++ stl::priority queue 使用 2 个键排序不正确

Posted

技术标签:

【中文标题】c++ stl::priority queue 使用 2 个键排序不正确【英文标题】:cpp stl::priority queue using 2 keys not sorting correctly 【发布时间】:2018-11-01 03:05:53 【问题描述】:

我已经定义了一个结构如下:

using namespace std; 
struct Person 
    int id; 
    int age; 
    string country_of_origin; 

;

我正在尝试使用 STL 优先级队列类根据 id 按升序对人员进行排序,并根据原籍国按字典顺序对匹配 id 的值进行排序。以下是我的代码:

#include <queue> 
#include <vector> 
#include <iostream>
#include <queue>
#include <string> 

using namespace std; 
struct Person 
    int id; 
    int age; 
    string country_of_origin; 

;

struct PersonCompare

    bool operator()(const Person &p1, const Person &p2) const
    
        if (p1.id>p2.id) 
            return true; 
         else if (p1.country_of_origin>p2.country_of_origin)
            return true; 
          else 
            return false; 
        
    
;




int main(int argc, char ** argv)

    Person p=1,2,"Zimbabwe"; 
    Person q=3,4,"New Zealand";
    Person r=5,7,"Wales"; 
    Person s=2,3,"India";
    Person t=1,4,"Sri Lanka"; 
    Person u=1,4,"Benin"; 
    priority_queue<Person,vector<Person>,PersonCompare> queue;
    queue.push(p); 
    queue.push(q); 
    queue.push(r); 
    queue.push(s); 
    queue.push(t); 
    queue.push(u);
    while (!queue.empty())
    
        Person p = queue.top();
        cout << p.id << "\t"<<p.age<<"\t"<<p.country_of_origin<<endl;  
        queue.pop();
    


我得到的输出是:

1       4       Benin
2       3       India
3       4       New Zealand
1       4       Sri Lanka
1       2       Zimbabwe
5       7       Wales

代替:

1       4       Benin
1       4       Sri Lanka
1       2       Zimbabwe
2       3       India
3       4       New Zealand
5       7       Wales 

为什么会这样?

【问题讨论】:

else if (p1.country_of_origin&gt;p2.country_of_origin) 应该是else if (p1.id == p2.id &amp;&amp; p1.country_of_origin &gt; p2.country_of_origin) 【参考方案1】:

您可以通过对第一个字段进行排序来进行字典比较,只有当它们相等时,然后测试第二个字段以打破平局。如果按如下方式重写比较器,它应该可以工作:

struct PersonCompare

    bool operator()(const Person &p1, const Person &p2) const
    
        if (p1.id > p2.id) 
            return true; 
         else if (p1.id < p2.id) 
            return false;
        
        return p1.country_of_origin > p2.country_of_origin;
    
;

另一种方法是使用std::tie,它更简洁,并且可以正确地进行字典比较:

#include <tuple>

struct PersonCompare

    bool operator()(const Person &p1, const Person &p2) const
    
        return std::tie(p1.id, p1.country_of_origin) > std::tie(p2.id, p2.country_of_origin);
    
;

【讨论】:

以上是关于c++ stl::priority queue 使用 2 个键排序不正确的主要内容,如果未能解决你的问题,请参考以下文章

C++ STL priority_queue容器适配器详解

c++ stl::priority queue 使用 2 个键排序不正确

[ C++ ] STL priority_queue(优先级队列)使用及其底层模拟实现,容器适配器,deque(双端队列)原理了解

STL priority_queue 的自定义分配器

STL priority_queue

STL priority_queue 优先队列 小记