web-dev-qa-db-fra.com

Comment utiliser la liste de priorités STL pour les objets?

class Person
{
public:
    int age;
};

Je souhaite stocker les objets de la classe Person dans une file d'attente prioritaire.

priority_queue< Person, vector<Person>, ??? >

Je pense que je dois définir une classe pour la comparaison, mais je n'en suis pas sûr.

Aussi, quand on écrit,

priority_queue< int, vector<int>, greater<int> > 

Comment fonctionne le plus grand?

64
user2441151

Vous devez fournir une comparaison d'ordre strict stricte valide pour le type stocké dans la file d'attente, Person dans ce cas. La valeur par défaut consiste à utiliser std::less<T>, ce qui donne un résultat équivalent à operator<. Cela repose sur son propre type stocké en ayant un. Donc, si vous deviez mettre en œuvre

bool operator<(const Person& lhs, const Person& rhs); 

cela devrait fonctionner sans autre changement. La mise en œuvre pourrait être

bool operator<(const Person& lhs, const Person& rhs)
{
  return lhs.age < rhs.age;
}

Si le type n'a pas de comparaison naturelle "inférieur à", il serait plus logique de fournir votre propre prédicat, au lieu du std::less<Person> par défaut. Par exemple,

struct LessThanByAge
{
  bool operator()(const Person& lhs, const Person& rhs) const
  {
    return lhs.age < rhs.age;
  }
};

puis instancier la file d'attente comme ceci:

std::priority_queue<Person, std::vector<Person>, LessThanByAge> pq;

En ce qui concerne l'utilisation de std::greater<Person> comme comparateur, cela utiliserait l'équivalent de operator> et aurait pour effet de créer une file d'attente avec la priorité inversée WRT comme casse par défaut. Cela nécessiterait la présence d'un operator> pouvant fonctionner sur deux instances Person.

98
juanchopanza

Vous écririez une classe de comparaison, par exemple:

struct CompareAge {
    bool operator()(Person const & p1, Person const & p2) {
        // return "true" if "p1" is ordered before "p2", for example:
        return p1.age < p2.age;
    }
};

et l'utiliser comme argument de comparaison:

priority_queue<Person, vector<Person>, CompareAge>

Utiliser greater donne l'ordre inverse à la valeur par défaut less, ce qui signifie que la file d'attente vous donnera la valeur la plus basse au lieu de la plus haute.

42
Mike Seymour

Une file d'attente prioritaire est un type de données abstrait qui capture l'idée d'un conteneur auquel des "priorités" sont attachées aux éléments. Un élément de priorité maximale apparaît toujours au début de la file d'attente. Si cet élément est supprimé, l'élément suivant de priorité la plus élevée passe au premier plan. 

La bibliothèque standard C++ définit un modèle de classe priority_queue, avec les opérations suivantes:

Push : insère un élément dans la file d'attente prioity.

top : Retourne (sans le supprimer) un élément de priorité la plus élevée de la file d'attente des priorités.

pop : supprime un élément de la priorité la plus élevée.

taille : Retourne le nombre d'éléments dans la file d'attente prioritaire.

empty : Renvoie true ou false selon que la file d'attente prioritaire est vide ou non.

L'extrait de code suivant montre comment créer deux files d'attente prioritaires, l'une pouvant contenir des entiers et l'autre pouvant contenir des chaînes de caractères:

#include <queue>

priority_queue<int> q1;
priority_queue<string> q2;

Voici un exemple d'utilisation de la file d'attente prioritaire:

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

using namespace std;  // This is to make available the names of things defined in the standard library.

int main()
{
    piority_queue<string> pq; // Creates a priority queue pq to store strings, and initializes the queue to be empty.

    pq.Push("the quick");
    pq.Push("fox");
    pq.Push("jumped over");
    pq.Push("the lazy dog");

    // The strings are ordered inside the priority queue in lexicographic (dictionary) order:
    // "fox", "jumped over", "the lazy dog", "the quick"
    //  The lowest priority string is "fox", and the highest priority string is "the quick"

    while (!pq.empty()) {
       cout << pq.top() << endl;  // Print highest priority string
       pq.pop();                    // Remmove highest priority string
    }

    return 0;
}

Le résultat de ce programme est:

the quick
the lazy dog
jumped over
fox

Puisqu'une file d'attente suit une discipline prioritaire, les chaînes sont imprimées de la priorité la plus élevée à la plus basse.

Parfois, il est nécessaire de créer une file d'attente prioritaire pour contenir des objets définis par l'utilisateur. Dans ce cas, la file d'attente des priorités doit connaître le critère de comparaison utilisé pour déterminer quels objets ont la priorité la plus élevée. Ceci est fait au moyen d'un objet fonction appartenant à une classe qui surcharge l'opérateur (). Overloaded () agit en tant que <dans le but de déterminer les priorités. Par exemple, supposons que nous voulions créer une file d'attente prioritaire pour stocker des objets Time. Un objet Time a trois champs: heures, minutes, secondes:

struct Time {
    int h; 
    int m; 
    int s;
};

class CompareTime {
    public:
    bool operator()(Time& t1, Time& t2) // Returns true if t1 is earlier than t2
    {
       if (t1.h < t2.h) return true;
       if (t1.h == t2.h && t1.m < t2.m) return true;
       if (t1.h == t2.h && t1.m == t2.m && t1.s < t2.s) return true;
       return false;
    }
}

Une file d'attente prioritaire pour stocker des temps selon le critère de comparaison ci-dessus serait définie comme suit:

priority_queue<Time, vector<Time>, CompareTime> pq;

Here is a complete program:

#include <iostream>
#include <queue>
#include <iomanip>

using namespace std;

struct Time {
    int h; // >= 0
    int m; // 0-59
    int s; // 0-59
};

class CompareTime {
public:
    bool operator()(Time& t1, Time& t2)
    {
       if (t1.h < t2.h) return true;
       if (t1.h == t2.h && t1.m < t2.m) return true;
       if (t1.h == t2.h && t1.m == t2.m && t1.s < t2.s) return true;
       return false;
    }
};

int main()
{
    priority_queue<Time, vector<Time>, CompareTime> pq;

    // Array of 4 time objects:

    Time t[4] = { {3, 2, 40}, {3, 2, 26}, {5, 16, 13}, {5, 14, 20}};

    for (int i = 0; i < 4; ++i)
       pq.Push(t[i]);

    while (! pq.empty()) {
       Time t2 = pq.top();
       cout << setw(3) << t2.h << " " << setw(3) << t2.m << " " <<
       setw(3) << t2.s << endl;
       pq.pop();
    }

    return 0;
}

Le programme imprime les heures du dernier au dernier:

5  16  13
5  14  20
3   2  40
3   2  26

Si nous voulions que les temps les plus anciens aient la priorité la plus élevée, nous redéfinirions CompareTime comme suit:

class CompareTime {
public:
    bool operator()(Time& t1, Time& t2) // t2 has highest prio than t1 if t2 is earlier than t1
    {
       if (t2.h < t1.h) return true;
       if (t2.h == t1.h && t2.m < t1.m) return true;
       if (t2.h == t1.h && t2.m == t1.m && t2.s < t1.s) return true;
       return false;
    }
};
18
Sandhyalal Kumar

Ce morceau de code peut aider ..

#include <bits/stdc++.h>
using namespace std;    

class node{
public:
    int age;
    string name;
    node(int a, string b){
        age = a;
        name = b;
    }
};

bool operator<(const node& a, const node& b) {

    node temp1=a,temp2=b;
    if(a.age != b.age)
        return a.age > b.age;
    else{
        return temp1.name.append(temp2.name) > temp2.name.append(temp1.name);
    }
}

int main(){
    priority_queue<node> pq;
    node b(23,"prashantandsoon..");
    node a(22,"prashant");
    node c(22,"prashantonly");
    pq.Push(b);
    pq.Push(a);
    pq.Push(c);

    int size = pq.size();
    for (int i = 0; i < size; ++i)
    {
        cout<<pq.top().age<<" "<<pq.top().name<<"\n";
        pq.pop();
    }
}

Sortie: 

22 prashantonly
22 prashant
23 prashantandsoon..
2
enig123

Nous pouvons définir un comparateur défini par l'utilisateur: .Le code ci-dessous peut vous être utile.

Extrait de code :

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

contribution :

batman 2
goku 9
Mario 4 

Sortie  

goku 9
Mario 4
batman 2 

0
rashedcs