Ich habe das Profiling von Nate Kohl neu gemacht und habe unterschiedliche Ergebnisse erhalten. In meinem Testfall ist das direkte Sortieren des Vektors immer effizienter als die Verwendung eines Sets. Ich habe eine neue, effizientere Methode hinzugefügt, die ein unordered_set
verwendet.
Bedenken Sie, dass die Methode unordered_set
nur funktioniert, wenn Sie eine gute Hashfunktion für den Typ haben, den Sie eindeutig und sortiert benötigen. Für ints ist das einfach! (Die Standardbibliothek bietet eine Standard-Hashfunktion, die einfach die Identitätsfunktion ist.) Vergessen Sie außerdem nicht am Ende zu sortieren, da unordered_set, naja, ungeordnet ist :)
Ich habe einige Nachforschungen in der Implementierung von set
und unordered_set
gemacht und festgestellt, dass der Konstruktor tatsächlich für jedes Element einen neuen Knoten erstellt, bevor er den Wert überprüft, um zu bestimmen, ob es tatsächlich eingefügt werden sollte (zumindest in der Visual Studio-Implementierung).
Hier sind die 5 Methoden:
f1: Nur Verwendung von Vektor
, sort
+ eindeutig
sort( vec.begin(), vec.end() );
vec.erase( unique( vec.begin(), vec.end() ), vec.end() );
f2: Umwandlung in ein Set
(Verwendung eines Konstruktors)
set s( vec.begin(), vec.end() );
vec.assign( s.begin(), s.end() );
f3: Umwandlung in ein Set
(manuell)
set s;
for (int i : vec)
s.insert(i);
vec.assign( s.begin(), s.end() );
f4: Umwandlung in ein unordered_set
(Verwendung eines Konstruktors)
unordered_set s( vec.begin(), vec.end() );
vec.assign( s.begin(), s.end() );
sort( vec.begin(), vec.end() );
f5: Umwandlung in ein unordered_set
(manuell)
unordered_set s;
for (int i : vec)
s.insert(i);
vec.assign( s.begin(), s.end() );
sort( vec.begin(), vec.end() );
Ich habe den Test mit einem Vektor von 100.000.000 zufällig aus den Bereichen [1,10], [1,1000] und [1,100000] gewählten ints durchgeführt
Die Ergebnisse (in Sekunden, kleiner ist besser):
Bereich f1 f2 f3 f4 f5
[1,10] 1.6821 7.6804 2.8232 6.2634 0.7980
[1,1000] 5.0773 13.3658 8.2235 7.6884 1.9861
[1,100000] 8.7955 32.1148 26.5485 13.3278 3.9822
4 Stimmen
Ich gehe davon aus, dass Sie keine Möglichkeit haben, vor dem Einfügen zu überprüfen, um Duplikate von Anfang an zu vermeiden?
1 Stimmen
Richtig. Das wäre ideal.
45 Stimmen
Ich würde vorschlagen, den obigen Code zu korrigieren oder deutlich darauf hinzuweisen, dass er FALSCH ist. std::unique geht davon aus, dass der Bereich bereits sortiert ist.
2 Stimmen
Unter Verwendung eines Sets
0 Stimmen
Sie müssen zuerst sortieren und dann löschen + eindeutig