【发布时间】:2012-02-07 14:33:19
【问题描述】:
我有以下结构
struct node{
float val;
int count;
}
我有这个结构的几个对象。现在,我想将这些对象插入到 STL 的优先级队列中,以便优先级队列按计数对项目进行排序。关于如何做到这一点的任何想法?最好是最小堆。我知道如何对原始数据类型执行上述操作,而不是结构
【问题讨论】:
标签: c++ priority-queue min-heap
我有以下结构
struct node{
float val;
int count;
}
我有这个结构的几个对象。现在,我想将这些对象插入到 STL 的优先级队列中,以便优先级队列按计数对项目进行排序。关于如何做到这一点的任何想法?最好是最小堆。我知道如何对原始数据类型执行上述操作,而不是结构
【问题讨论】:
标签: c++ priority-queue min-heap
重载
bool operator<(const node& a, const node& b) {
return a.count > b.count;
}
我已经反转了比较以实现最小堆,而无需将额外的参数传递给优先级队列。 现在你像这样使用它:
priority_queue<node> pq;
...
编辑:看看这篇似乎几乎完全相同的帖子:STL Priority Queue on custom class
【讨论】:
template<class T> priority_queue)。在内部,它使用
return a.count < b.count;吗?
I have reversed the comparison to achieve min heap wihtout passing extra arguments to the priority queue.
Define overloaded operators only if their meaning is obvious, unsurprising, and consistent with the corresponding built-in operators. - 来自 Google C++ 风格指南。
#include <iostream>
#include <queue>
#include <vector>
using namespace std;
class Boxer{
public:
string name;
int strength;
};
struct Comp{
bool operator()(const Boxer& a, const Boxer& b){
return a.strength<b.strength;
}
};
int main(){
Boxer boxer[3];
boxer[0].name="uday", boxer[0].strength=23;
boxer[1].name="manoj", boxer[1].strength=33;
boxer[2].name="rajiv", boxer[2].strength=53;
priority_queue< Boxer, vector<Boxer>, Comp> pq;
pq.push(boxer[0]);
pq.push(boxer[1]);
pq.push(boxer[2]);
Boxer b = pq.top();
cout<<b.name;
//result is Rajiv
return 0;
}
【讨论】:
使用greater作为比较函数可以使用优先队列作为最小堆,
#include <bits/stdc++.h>
using namespace std;
int main()
{
priority_queue<int,vector<int>,greater<int> >pq;
pq.push(1);
pq.push(2);
pq.push(3);
while(!pq.empty())
{
int r = pq.top();
pq.pop();
cout << r << " ";
}
return 0;
}
通过更改符号来插入值(使用减号 (-) 表示正数,使用加号 (+) 表示负数,我们可以以相反的顺序使用优先级队列。
int main()
{
priority_queue<int>pq2;
pq2.push(-1); //for +1
pq2.push(-2); //for +2
pq2.push(-3); //for +3
pq2.push(4); //for -4
while(!pq2.empty())
{
int r = pq2.top();
pq2.pop();
cout << -r << " ";
}
return 0;
}
对于自定义数据类型或类,我们需要告诉优先级队列一种知道它将按什么顺序对我们的数据进行排序的方法。
struct compare
{
bool operator()(const int & a, const int & b)
{
return a>b;
}
};
int main()
{
priority_queue<int,vector<int>,compare> pq;
pq.push(1);
pq.push(2);
pq.push(3);
while(!pq.empty())
{
int r = pq.top();
pq.pop();
cout << r << " ";
}
return 0;
}
对于自定义结构或类,您可以按任意顺序使用priority_queue。假设,我们想根据薪水降序排列人,如果平,则根据他们的年龄。
struct people
{
int age,salary;
};
struct compare {
bool operator()(const people & a, const people & b)
{
if(a.salary==b.salary)
{
return a.age>b.age;
} else {
return a.salary>b.salary;
}
}
};
int main()
{
priority_queue<people,vector<people>,compare> pq;
people person1,person2,person3;
person1.salary=100;
person1.age = 50;
person2.salary=80;
person2.age = 40;
person3.salary = 100;
person3.age=40;
pq.push(person1);
pq.push(person2);
pq.push(person3);
while(!pq.empty())
{
people r = pq.top();
pq.pop();
cout << r.salary << " " << r.age << endl;
}
运算符重载也可以得到同样的结果:
struct people
{
int age,salary;
bool operator< (const people & p) const
{
if(salary==p.salary)
{
return age>p.age;
} else {
return salary>p.salary;
}
}
};
在主函数中:
priority_queue<people> pq;
people person1,person2,person3;
person1.salary=100;
person1.age = 50;
person2.salary=80;
person2.age = 40;
person3.salary = 100;
person3.age=40;
pq.push(person1);
pq.push(person2);
pq.push(person3);
while(!pq.empty())
{
people r = pq.top();
pq.pop();
cout << r.salary << " " << r.age << endl;
}
【讨论】:
您需要为该结构提供operator<。比如:
bool operator<(node const& x, node const& y) {
return x.count < y.count;
}
现在您可以使用标准库中的优先级队列。
【讨论】:
从C++11开始,可以写
auto comparer = [](const auto& a, const auto& b) {
return a.priority < b.priority;
};
std::priority_queue<Item, std::vector<Item>, decltype(comparer)> queue(comparer);
【讨论】:
我们可以定义用户定义的比较器类:
#include<bits/stdc++.h>
using namespace std;
struct man
{
string name;
int priority;
};
class comparator
{
public:
bool operator()(const man& a, const man& b)
{
return a.priority<b.priority;
}
};
int main()
{
man arr[5];
priority_queue<man, vector<man>, comparator> pq;
for(int i=0; i<3; i++)
{
cin>>arr[i].name>>arr[i].priority;
pq.push(arr[i]);
}
while (!pq.empty())
{
cout<<pq.top().name<<" "<<pq.top().priority;
pq.pop();
cout<<endl;
}
return 0;
}
【讨论】:
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
class Person
{
public:
string name;
int age;
Person(string str,int num)
{
name = str;
age = num;
}
};
// FUNCTOR
class compare
{
public:
bool operator()(Person a,Person b)
{
cout << "Comparing " << a.age << " with " << b.age << endl;
return a.age < b.age;
}
};
int main()
{
int n;
cin >> n;
priority_queue <Person, vector<Person> , compare> pq;
for(int i=1;i<=n;i++)
{
string name;
int x;
cin >> name;
cin >> x;
Person p(name,x);
pq.push(p);
}
int k = 3;
for(int i=0;i<k;i++)
{
Person p = pq.top();
pq.pop();
cout << p.name << " " << p.age << endl;
}
return 0;
}
Operator() 通常也被重载以实现函子或函数对象。例如,我们有一个结构 Person ,它有一些默认的按年龄搜索和排序人的方法,但是我们希望我们的自定义方法带有一些其他参数,比如权重,所以我们可以使用我们自己的自定义函子。优先级队列就是这样一种容器,它接受一个函子,因此它知道如何对自定义数据类型的对象进行排序。每次要进行比较时,都会实例化一个类 compare 的对象,并传入两个 person 类的对象进行比较。
【讨论】: