18 Stimmen

Bester Algorithmus zur Prüfung, ob ein Vektor sortiert ist

Wie kann man am besten überprüfen, ob ein std::vector sortiert ist? Gibt es etwas Schnelleres als eine Schleife, die prüft, ob v[i]<=v[i+1] ? Ist es schneller/sauberer mit Iteratoren? Oder ist es tatsächlich besser, einfach die sort jedes Mal (obwohl der Fall "v ist bereits sortiert" recht häufig vorkommt)?

Wir können sicher davon ausgehen, dass der Vektor nur PODs enthält, in der Regel float s und manchmal double s und int s.

Die Größe des Vektors ist nicht trivial (in der Regel einige tausend Elemente), aber nicht extrem (keine Gigabyte-Größe).

  • In einigen Fällen sortieren wir den Vektor unmittelbar danach, in anderen Fällen jedoch nicht (das ist ein Fehlerfall unseres Algorithmus).
  • wir verwenden bereits ein Flag "IsSorted", wann immer dies möglich ist.

0 Stimmen

Sortieren Sie sofort aus, wenn nicht sortiert wird? Das könnte einen Unterschied machen.

28voto

Deestan Punkte 15779

Gibt es etwas Schnelleres als eine Schleife die überprüft, ob v[i]<=v[i+1] ist?

Nein.

Wenn Sie dies häufig überprüfen möchten, sollten Sie eine Wrapper-Klasse erstellen, die ein Flag "sortiert" enthält, das zunächst auf False gesetzt wird, sobald ein Element hinzugefügt wird, und eine Member-Funktion sort() hinzufügen, die das Flag nach dem Sortieren auf True setzt.

0 Stimmen

Das ist eine gute Idee! Und wir tun es bereits, wann immer es möglich ist :). Aber in diesem Fall, wir sind mit guten alten vanillay std::vector stecken...

0 Stimmen

Oh gut ... das war es, was mir in den Sinn kam, als ich die Frage sah ... zum Glück scheine ich richtig gedacht zu haben.

25voto

ShreevatsaR Punkte 37033

Der beste Weg ist die Verwendung von std::is_sorted :

is_sorted(v.begin(), v.end())

:-)

2 Stimmen

Das ist eine SGI-Erweiterung. Ich habe sie mit GCC, aber nicht mit VC++7. Stimmt, es ist nur ein Kopieren-Einfügen entfernt! Wie auch immer, ich muss seinen Iterator-basierten Ansatz mit dem Index-basierten Ansatz vergleichen... Dann werden wir sagen können, dass es "der beste Weg" ist :)

6 Stimmen

C++11 hat jetzt is_sorted zu

16voto

Scott Langham Punkte 55597

Mehrere Cpu-Kerne in Betracht ziehen

Dies hängt von Ihrer Plattform und der Anzahl der Elemente im Vektor ab. Sie müssen einen Benchmark durchführen, um das Beste herauszufinden.

Es ist nicht möglich, darauf zu antworten: Gibt es etwas Schnelleres als eine Schleife, die überprüft, ob v[i]<=v[i+1] ist?
Mit: Nein.

Weil... Computer heutzutage mehrere Prozessoren/Kerne/Hyperthreading haben. Es kann also sehr viel schneller sein, den Paralellismus im Computer auszunutzen, indem man die Arbeit der Überprüfung auf mehrere Threads aufteilt, so dass jede CPU einen kleinen Bereich parallel überprüfen kann.

Es ist wahrscheinlich am besten, dies über eine Bibliotheksfunktion zu tun, anstatt es selbst zu implementieren. Neue Versionen von Bibliotheken werden den Parallismus ausnutzen. Wenn Sie sich also für std::sort entscheiden, werden Sie wahrscheinlich feststellen, dass neuere Implementierungen der STL die Operation parallel für Sie durchführen, ohne dass Sie sich darum kümmern müssen. Ich weiß nicht, ob es bereits verfügbare Versionen der STL gibt, die dies tun, aber es lohnt sich, an den Bibliotheksfunktionen festzuhalten, so dass diese Optimierung für Sie da ist, wenn Sie auf eine Version aktualisieren, die dies tut, ohne dass Sie irgendwelche Änderungen vornehmen müssen.

0 Stimmen

+1 aufschlussreich. Leider ist meine is_sorted-Implementierung (die mit einer ziemlich alten gcc-Version (3.4.x) kam) erbärmlich einfach. Außerdem, ist nicht die Speicherbandbreite der begrenzende Faktor für eine so einfache Schleife?

0 Stimmen

Es ist schwierig zu sagen, ob die Speicherbandbreite eine Einschränkung darstellt. Das hängt von Ihrer Plattform, der Größe des Vektors, der Größe eines Elements im Vektor, der für den Vergleich benötigten Zeit usw. ab. Deshalb sind Zeitmessung/Benchmarking erforderlich, wenn Sie herausfinden wollen, wie Sie jedes Quäntchen Saft herausquetschen können.

12voto

newacct Punkte 114757
std::adjacent_find(v.begin(), v.end(), std::greater<type>()) == v.end()

6voto

endian Punkte 4167

Natürlich kenne ich Ihre Problemdomäne nicht, also ignorieren Sie mich bitte, wenn das, was ich sage, nicht relevant ist, aber es scheint mir, dass, wenn ich verlange, dass eine Sammlung immer sortiert ist, wenn ich auf sie zugreife, eine natürlich unsortierte Sammlung wie eine vector<T> ist vielleicht nicht die beste Wahl.

1 Stimmen

Ältere Formate sowie Datenkompatibilität. Außerdem ist die Sortierung, sobald sie abgeschlossen ist (und das ist sie nicht dass lange ein Teil des Prozesses), ist der Zugriff auf einen Vektor verdammt schnell! Aber ich begrüße Ihre Art zu denken "löse ich das richtige Problem?".

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X