2009-06-12 3 views
9

Meine Priorität Warteschlange erklärt wie:Wie Implementieren Methode Sortierung für ein C++ priority_queue mit Zeigern

std::priority_queue<*MyClass> queue; 

class MyClass { 
    bool operator<(const MyClass* m) const; 
} 

nicht, um die Elemente in der Warteschlange zu sortieren.

Was ist los? Ich würde nicht gerne eine andere (Compare) Klasse implementieren.

Antwort Zusammenfassung:

Das Problem ist, werden die Zeiger Adressen sortiert. Der einzige Weg, dies zu vermeiden, ist eine Klasse, die die Zeiger vergleicht.

std::priority_queue<*MyClass, vector<*MyClass>, MyClass::CompStr > queue; 

class MyClass { 
    struct CompStr { 
     bool operator()(MyClass* m1, MyClass* m2); 
    } 
} 
+0

Ich kann wirklich nicht folgen. Ich gebe Ihnen die Antwort mit einer zusätzlichen Trennung der Bedenken und ich bekomme 2 Stimmen. Warum muss MyClass wissen, dass es mit dem Zeiger verglichen wird? Was ist mit open-closed-Prinzip, was werden Sie tun, wenn Sie entscheiden, dass Sie auch eine Std :: priority_que von Werttypen anstelle von Zeigern benötigen. – TimW

Antwort

11

Geben Sie die Que den Vergleich functor ptr_less.

Wenn Sie wollen, dass die ptr_less mit dem Rest der std-Bibliothek (Bindemittel, Komponisten, ...) kompatibel zu sein:

template<class T> 
struct ptr_less 
    : public binary_function<T, T, bool> { 
     bool operator()(const T& left, const T& right) const{ 
      return ((*left) <(*right)); 
     } 
}; 

std::priority_queue<MyClass*, vector<MyClass*>, ptr_less<MyClass*> > que; 

Ansonsten können Sie mit der vereinfachten Version wegkommen:

struct ptr_less { 
    template<class T> 
    bool operator()(const T& left, const T& right) const { 
     return ((*left) <(*right)); 
    } 
}; 

std::priority_queue<MyClass*, vector<MyClass*>, ptr_less > que; 
+0

Kann mir bitte sagen, was ist falsch und warum -1, dieser Code funktioniert und ist gültig C++ - Code. – TimW

+0

Es macht es schwierig mit dem Template-Operator und Zeug. Immer noch muss der Operator zwischen den beiden Zeigern für die spezifische MyClass irgendwo implementiert werden. –

+0

Also meine Lösung ist generisch? Natürlich brauchen Sie eine Möglichkeit, zwei MyClass-Objekte zu vergleichen. Jetzt benötigen Sie einen speziellen Operator, um zwei MyClass-Zeiger zu vergleichen, und ich muss zwei MyClass-Objekte etwas natürlicher vergleichen. – TimW

4

Der Betreiber <() Sie bietet ein MyClass-Objekt mit einem Zeiger auf ein MyClass Objekt vergleichen hast:

nun als umgesetzt. Aber deine Warteschlange enthält nur Zeiger (glaube ich). Sie benötigen eine Vergleichsfunktion, die zwei Zeiger als Parameter akzeptiert.

All dies basiert auf einigen Annahmen - bitte posten Sie Ihren tatsächlichen Code, kopieren und einfügen.

4

Da Ihre priority_queue nur Zeigerwerte enthält, verwendet sie den Standardvergleichsoperator für die Zeiger - dies sortiert sie nach Adresse, die offensichtlich nicht das ist, was Sie wollen. Wenn Sie priority_queue ändern, um die Klasseninstanzen nach Wert zu speichern, wird der von Ihnen definierte Operator verwendet. Oder Sie müssen eine Vergleichsfunktion bereitstellen.

3

nicht über die Prioritätswarteschlange Sachen sicher, weil ich nie, aber es benutzt habe eine gerade Art zu tun, können Sie dies tun:

class A 
{ 
    friend struct ComparePtrToA; 
public: 
    A(int v=0):a(v){} 
private: 
    int a; 
}; 

struct ComparePtrToA 
{ 
    bool operator()(A* a1, A* a2) {return a1->a < a2->a;} 
}; 

#include <vector> 
#include <algorithm> 
int _tmain(int argc, _TCHAR* argv[]) 
{ 
    vector<A*> someAs; 
    someAs.push_back(new A(1)); 
    someAs.push_back(new A(3)); 
    someAs.push_back(new A(2)); 
    sort(someAs.begin(), someAs.end(), ComparePtrToA()); 
} 

Beachten Sie die Speicherlecks, dies ist nur ein Beispiel ...

Weiterer Hinweis: Dies ist keine Implementierung der Prioritätswarteschlange! Der Vektor ist nur ein Beispiel für die Verwendung des Funktors, den ich erstellt habe, um zwei Objekte über ihre Zeiger zu vergleichen. Obwohl mir bewusst ist, was eine Prioritätswarteschlange ist und wie sie funktioniert, habe ich nie die STL-Funktionen verwendet, die sie implementieren.

Update: Ich denke TimW macht einige gültige Punkte. Ich weiß nicht, warum er so oft abgelehnt wurde. Ich denke, meine Antwort verbessert werden kann wie folgt:

class A 
{ 
public: 
    A(int v=0):a(v){} 
    bool operator<(const A& rhs) { return a < rhs.a; } 
private: 
    int a; 
}; 

struct ComparePtrToA 
{ 
    bool operator()(A* a1, A* a2) {return *a1 < *a2;} 
}; 

, die sauberer ist (vor allem, wenn Sie einen Container von Werten berücksichtigen zu müssen, anstatt Zeigern - keine weiteren Arbeiten erforderlich wären).

+1

Ich muss darauf hinweisen, dass dies eine sehr schlechte Methode ist, um eine Prioritätswarteschlange, Speicherlecks und so weiter zu implementieren. Wenn alles, was Sie wollen, ein sortiertes Array ist, dann ist es in Ordnung, aber eine Prioritätswarteschlange hat eine sehr unterschiedliche Implementierung mit besseren Leistungsgarantien für Dinge wie das erste Element herauszubekommen und Elemente einzufügen. –

+0

Ich denke, er verwendet nur sort() als Beispiel, so dass (a) er seinen Komparator im Arbeitscode anstatt allein präsentieren kann, aber (b) er priority_queue selbst nicht verwenden muss, was er sagt, dass er nicht vertraut ist mit ... –

+0

Diese Antwort gab die richtige Funktion für eine Comparer-Klasse zu implementieren. Es funktioniert für meine Prioritätswarteschlange. Natürlich berücksichtige ich, wie es mit meiner Erinnerung läuft. Es ist nicht zum Spaß, dass ich eine priority_queue von Zeigern brauche. –