Как заставить приоритетную очередь использовать переменную из пользовательского класса (по возрастанию / убыванию) - PullRequest
0 голосов
/ 14 мая 2018

У меня проблемы с использованием priority_queue в C ++, у меня есть вектор очередей с приоритетами, очереди с приоритетами содержат несколько Person объектов. Теперь я бы хотел, чтобы priority_queue расставил приоритеты для Person объектов в зависимости от их возраста. Итак, у меня есть что-то вроде этого:

class Person
{
public:
  string name;
  int height;
  int age;
};

std::vector<std::priority_queue<Person*>> Persons;

Как мне убедиться, что при добавлении человека в одну из приоритетных очередей ему назначается приоритет в зависимости от его возраста? И как бы я сделал это в порядке возрастания / убывания?

Ответы [ 4 ]

0 голосов
/ 14 мая 2018

На самом деле вам не нужен дополнительный вектор, который оборачивает ваш файл priority_queue, поскольку у самого priority_queue есть 2 дополнительных аргумента по умолчанию: (первый - это тип, в вашем случае Person *), второй - тип контейнера, а третий - предикат сравнения. ниже вы можете увидеть использование лямбда-функции в качестве предиката сравнения для вашей очереди приоритетов.

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

using namespace std;

class Person
{
public:
    string name;
    int height;
    int age;

    Person(string n, int h, int a): name(n), height(h), age(a) {}
};


ostream& operator<<(ostream &cout, const Person* p) {
    return cout << p->name << " height=" << p->height << " age=" << p->age << " ";
}

int main()
{
    auto cmp = [](const Person* pl, const Person* pr) {
        return (pl->age < pr->age);
    };

    priority_queue<Person*, vector<Person*>, decltype(cmp)> persons(cmp);

    persons.push(new Person("a", 100, 10));
    persons.push(new Person("b", 120, 20));
    persons.push(new Person("c", 110, 15));

    while (!persons.empty()) {
        cout << persons.top() << endl;
        persons.pop();
    }

    return 0;
}
0 голосов
/ 14 мая 2018

Вы можете реализовать так:

#include <iostream>
#include <queue>
#include <vector>
#include <string>
using namespace std;



class Person
{
public:
    string name;
    int height;
    int age;

};

struct OrderByAge
{
    bool operator() (Person const &a, Person const &b) { return a.age > b.age; }
};


int main() 
{
    vector<priority_queue<Person, std::vector<Person>,OrderByAge> > personPQVec{ 1 };

    Person p1{ "nitendra",5,39 };
    Person p2{ "bhosle",6,34 };
    Person p3{ "nit",4,33 };


    personPQVec[0].push(p1);
    personPQVec[0].push(p2);
    personPQVec[0].push(p3);


    while (!personPQVec[0].empty()) {

        cout << "Name: " << (personPQVec[0]).top().name << ", age: " << (personPQVec[0]).top().age << endl;
        (personPQVec[0]).pop();
    }
    system("pause");
    return 0;
}
0 голосов
/ 14 мая 2018

Вы можете передать предикат в качестве третьего параметра для определения порядка сортировки, объявив два предиката для вашего Person*

struct AscendingPersonPredicate
{
    bool operator() ( Person* p1, Person* p2) const
    {
        return p1->age < p2->age;
    }
};

struct DescendingPersonPredicate
{
    bool operator() ( Person* p1, Person* p2) const
    {
        return p1->age > p2->age;
    }
};

Затем объявите свой вектор как:

std::priority_queue<Person*, vector<Person*>, AscendingPersonPredicate> Persons;

или

std::priority_queue<Person*, vector<Person*>, DescendingPersonPredicate> Persons;
0 голосов
/ 14 мая 2018

std::priority_queue имеет интерфейс для того, что вам нужно.Он принимает три параметра шаблона:

template<
    class T,
    class Container = std::vector<T>,
    class Compare = std::less<typename Container::value_type>
> class priority_queue;

Третий параметр - это то, что вам нужно изменить для обработки сравнения элементов.

// make a functor to do the comparisons
struct comparator
{
    bool operator()(Person* lhs, Person* rhs) const {
        // sort by age
        return lhs->age < rhs->age; // switch the sign for reverse order
    }
};

// have a type alias for convenience (typedef is fine too)
using pqueue = std::priority_queue<Person*, std::vector<Person*>, comparator>;

int main() 
{
    std::vector<pqueue> persons; 
}
...