2012-11-14 11 views
9

Ich würde gerne wissen, ob wir eine zuvor erstellte Menge sortieren können. Wenn ich zuerst die Menge s_p2 erstelle, sortiere ich mit einem anderen Element point.getLength(). Aber nach der Benutzereingabe möchte ich die Elemente nach dem x-Wert point.getX() sortieren. Wie mache ich das?Sortieren von sets mit std :: sort

Es scheint, als hätte der Set-Container keine Sortierfunktion. Und ich werde empfohlen, Vektor zu verwenden. Aber Sätze können nur einzigartige Elemente speichern.

Q1: Wie kann ich einen Satz sortiere nach den Kriterien

Q2 abhängig: Wenn gesetzt nicht in der Lage ist, dies zu tun, als die STL-Container ist die beste Wahl und wie kann ich die Elemente in dem Behälter sortieren.

Antwort

11

liefern Sie kein set zurückgreifen kann, wie es sortiert Teil von der Art des jeweiligen set ist. Eine gegebene set hat eine feste Reihenfolge, die nicht geändert werden kann.

Sie könnten ein neues set mit den gleichen Daten relativ leicht erstellen. Erstellen Sie einfach einen neuen set, der nach den neuen Kriterien sortiert. Wenn Sie die beiden set s im selben Code verwenden möchten, müssen Sie den Zugriff auf das zugrunde liegende set abstrahieren.

Nun, wenn Sie seltene Lesevorgänge und Änderungen tun, ist die Verwendung einer vector, die Sie manuell sortieren oft eine bessere Idee. Sie können Duplikate entfernen, indem Sie das std::unique - erase Idiom verwenden.

+0

Vector ist in Ordnung mit mir. aber ich bin mir nicht sicher, wie man das std :: unique-erase implementiert. Kannst du beraten? –

+2

@ user1571494: Gegeben sei ein sortierter Vektor, 'v.resease (std :: unique (v.begin(), v.end()), v.end());' löscht Duplikate. –

+3

Beachten Sie, dass der obige Code @Mike schrieb 'operator ==', um sie zu vergleichen. Möglicherweise müssen Sie ein Prädikat übergeben, damit Sie nur Dinge sortieren, die äquivalent sind "(! (A Yakk

7

std::set speichert seine Mitglieder in einer sortierten Weise. Wenn Sie durch den Satz von .begin() zu .end() gehen, haben Sie eine sortierte Liste von Elementen.

Wenn Sie nicht die Standardsortierkriterien möchten, können Sie einen zweiten Template-Parameter zu std::set<>

+0

Yup .. ich verstehe. aber kann ich es neu sortieren –

+0

@ user1571494 - Nein, Sie können es nicht neu sortieren. Sie * können * die Elemente aus diesem 'std :: set <>' und in einen anderen Container kopieren - vielleicht ein 'std :: set' mit einem anderen Vergleichsschablonenparameter. –

+0

Ich glaube, Sätze akzeptieren einen Komparator oder ein Objekt (entweder zu einem Zeiger auf eine Funktion oder eine Klasse mit einem Funktionsaufrufoperator), die in der Lage ist, 2 Objekte in der Menge zu nehmen und eine absolute Reihenfolge zwischen ihnen zu bestimmen. Wenn Sie sich das Beispiel unten auf dieser Seite ansehen: http://www.cplusplus.com/reference/stl/set/set/, gibt es ein Beispiel für einen Satz mit einem benutzerdefinierten Vergleicher. – Wug

3

Sie können zwei Sets haben und sie synchron halten oder eins kopieren.

#include <iostream> 
#include <set> 

using namespace std; 

struct AB 
{ 
    AB(int a,int b) : _a(a),_b(b) {} 

    int _a; 
    int _b; 
}; 

struct byA 
{ 
    bool operator() (const AB& lhs, const AB& rhs) 
    { 
      return lhs._a <= rhs._a; 
    } 
}; 

struct byB 
{ 
    bool operator() (const AB& lhs, const AB& rhs) 
    { 
     return lhs._b <= rhs._b; 
    } 
}; 

typedef set<AB,byA> ByA; 
typedef set<AB,byB> ByB; 
typedef ByA::const_iterator ByAIt; 
typedef ByB::const_iterator ByBIt; 

void getByB(const ByA &sA,ByB &sB) 
{ 
    for(ByAIt iter=sA.begin(); iter!=sA.end();++iter) { 
     const AB &ab=*iter; 
     sB.insert(ab); 
    } 
} 

int main(int argc, const char **argv) 
{ 
    ByA sA; 
    sA.insert(AB(3,6)); 
    sA.insert(AB(1,8)); 
    sA.insert(AB(2,7)); 

    ByB sB; 
    getByB(sA,sB); 

    cout << "ByA:" << endl; 
    for(ByAIt iter=sA.begin(); iter!=sA.end();++iter) { 
     const AB &ab=*iter; 
     cout << ab._a << "," << ab._b << " "; 
    } 
    cout << endl << endl; 

    cout << "ByB:" << endl; 
    for(ByBIt iter=sB.begin(); iter!=sB.end();++iter) { 
     const AB &ab=*iter; 
     cout << ab._a << "," << ab._b << " "; 
    } 
    cout << endl; 
    return 0; 
} 

Programm kehrt: BJA 1,8 2,7 3,6

ByB: 3,6 2,7 1,8

Verwandte Themen