2017-09-23 4 views
0

Ich möchte einzigartig und in set<Foo, FooComp> bestellen.C++ Set Unique und Bestellung

Im unteren Code möchte ich eine eindeutige und Reihenfolge von b und c. Also, keine gleichen foo.a und bestellen Sie durch foo.b und foo.c.

Wie kann ich das tun?

struct Foo { 
    int a, b, c; 
    Foo(int a, int b, int c) : a(a), b(b), c(c) {} 
} 

struct FooComp { 
    bool operator() (const Foo& f, const Foo& s) const { 
     if (f.pattern == s.pattern) { 
      return false; 
     } 
     if (f.start == s.start) { 
      return f.length < s.length; 
     } 
     return f.start < s.start; 
    } 
} 

oder verwende ich andere STL oder Datenstrukturen?

+0

und ich denke, über Karte verwenden, 'als Schlüssel und' (b, c) 'als Wert a'. Aber, Karte ist nicht für diesen Fall entworfen (ich dachte). – Maybe

Antwort

0

Dies ist mit der Standardbibliothek nicht möglich.

Der Vergleichsoperator ist eng mit der Bestellung verbunden.

Obwohl er ein wenig schlechte Lösung in Bezug auf Leistung, können Sie eine Reihe haben, die alle Ihre Objekte enthalten, sortierten nach ‚a‘ nur mit:

struct Foo { 
    int a, b, c; 
    Foo(int a, int b, int c) : a(a), b(b), c(c) {} 
    bool operator<(const Foo& rhs) const { 
     return a < rhs.a; 
    } 
    friend ostream& operator<<(ostream&, const Foo&); 
}; 

Und dann, wann immer Sie wollen es sortieren, mit Ihre einzigartigen Algorithmus, kopieren sie sie einfach in einen Vektor und sortieren sie nach Ihren Bedürfnissen:

vector<Foo> v; 
std::copy(s.begin(), s.end(), std::back_inserter(v)); 
std::sort(v.begin(), v.end(), [](const Foo& lhs, const Foo& rhs){ return (lhs.b == rhs.b) ? lhs.c > rhs.c : lhs.b > rhs.b; }); 

Herausgegeben

Dies implementiert die Logik, die Sie in Ihrem Beispiel für Pastebin verwendet haben. Ganze Probe here

+0

Das funktioniert nicht wie ich denke. In diesem Code (https://pastebin.com/dCBpcQB2) erwarte ich 1, 2, 3 2, 3, 1 3, 5, 2 aber Ergebnis ist 1, 2, 3 2, 3, 1 3, 5, 2 1, 5, 7 – Maybe

+0

@Maybe, habe ich meine Antwort –

+0

aktualisiert und ich kenne diese Antwort, aber das ist die beste Antwort? Ich bin mir nicht sicher ... – Maybe

0

Es gibt eine fertige Bibliothek für diese Art von Sache in Boost namens boost.multi_index.

Es ermöglicht die Deklaration eines Containers, der mehrere Indizes und ihre Einschränkungen erfüllt.

Es ist ein wenig archaisch und könnte mit etwas Liebe tun, aber es macht den Job.

Sie mit so etwas wie dies starten:

struct Foo { 
    int a, b, c; 
    Foo(int a, int b, int c) : a(a), b(b), c(c) {} 
}; 

#include <tuple> 
#include <type_traits> 
#include <utility> 
#include <boost/multi_index_container.hpp> 
#include <boost/multi_index/member.hpp> 
#include <boost/multi_index/ordered_index.hpp> 


struct get_a 
{ 
    using result_type = int const&; 
    result_type operator()(Foo const& l) const { 
     return l.a; 
    } 
}; 

struct get_bc 
{ 
    using result_type = std::tuple<int const&, int const&>; 

    result_type operator()(Foo const& l) const { 
     return std::tie(l.b, l.c); 
    } 
}; 

namespace foo { 
    using namespace boost; 
    using namespace boost::multi_index; 

    struct by_a {}; 
    struct by_bc {}; 

    using FooContainer = 
multi_index_container 
< 
    Foo, 
    indexed_by 
    < 
     ordered_unique<tag<by_a>, get_a>, 
     ordered_non_unique<tag<by_bc>, get_bc> 
    > 
>; 
} 

int main() 
{ 
    foo::FooContainer foos; 

    foos.insert(Foo{ 1, 2,3 }); 
    foos.insert(Foo{ 2, 2,4 }); 

} 
+0

wow, vielen Dank, aber Boost-Bibliothek ist nicht meine Umgebung erlaubt. – Maybe