Sortiere eine Matrix, die als Vektor-Doppelpunkt definiert ist

8

Angenommen, ich habe eine quadratische Matrix A der Größe n , definiert als std::vector<double> .

%Vor%

Auf die Elemente der Matrix wird wie üblich zugegriffen:

%Vor%

Ich muss die Zeilen der Matrix in aufsteigender Reihenfolge in Bezug auf die erste Spalte sortieren.

Die Funktion qsort erlaubt es mir, Arrays und Funktionszeiger zu verwenden, aber ich würde gerne einen Weg finden, dies mit Vektoren und std::sort zu erreichen.

Beachten Sie auch, dass ich meine Matrix aus Leistungsgründen nicht als Vektorenvektor definieren möchte.

Bearbeiten:

Die Funktion, die ich an qsort übergeben habe:

%Vor%

Und der Anruf:

%Vor%     
Dooggy 03.11.2016, 09:31
quelle

3 Antworten

3

std::sort arbeitet mit Iteratoren und kümmert sich nicht um die Iterator-Implementierung. Wenn Sie also ein struct RowIter definieren, das ein std::vector<double>& matrix umhüllt, mit einem Mitglied size_t RowSize für operator+(size_t) (und operator- , operator++ usw.) und ein Row operator*() const , dann kann std::sort nach sortieren dieser Iterator.

Immer noch ein bisschen mehr Arbeit als qsort , aber es würde auf Nicht-POD-Typen verallgemeinern.

    
MSalters 03.11.2016 10:28
quelle
2

Es ist möglich, qsort durch std::sort zu ersetzen, um das zugrunde liegende Array zu sortieren, aber Sie müssen definieren:

  • a Zeilentyp, der direkt auf den zugrunde liegenden Speicher des Vektors zugreift - Sie können hier keinen Vektor verwenden, denn selbst wenn ein Array oder Arrays immer noch ein Array ist, ist ein Vektor von Vektoren kein Vektor mit quadratischer Größe. Schlimmer noch, ich kenne keine Möglichkeit, einem Vektor einen vorhandenen Speicher zuzuordnen. Dieser Zeilentyp muss move-constructible und move-assignable sein und swap korrekt unterstützen.
  • ein RandomAccessIterator für diesen Row-Typ, der das Ende des zugrunde liegenden Arrays korrekt verarbeiten kann.

Es liegt an Ihnen, das zu tun, aber alle Versionen von Standard-C ++ unterstützen die C-Bibliothek explizit, so dass es keinen Schaden gibt, qsort in diesem Anwendungsfall zu verwenden, weil es viel einfacher ist und am Ende weniger Fehler -anfällig. Der qsort Weg benötigt nur 7 Zeilen, was leicht zu kontrollieren und zu überprüfen ist. Der nice C ++ Weg wird mindestens 2 Klassen mit nicht-trivialen Konstruktoren erfordern, so viel mehr Zeilen und viel mehr Möglichkeiten von Fehlern in ihnen.

Wenn Sie qsort wirklich nicht verwenden können, vielleicht für interne Codierungsregeln, dann würde ich einfach die Daten in einen Vektor von Vektoren kopieren, sie sortieren und die Daten zurück in den Anfangsvektor kopieren. Es beinhaltet 2 zusätzliche vollständige Kopien der Matrix, aber mindestens Standardklassen und erfordert weit weniger Codierung.

    
Serge Ballesta 03.11.2016 10:09
quelle
0

Die einfachste Lösung besteht darin, die qsort() beizubehalten und std::vector::data() zu verwenden, was einen Zeiger auf das erste Element zurückgibt, sodass Sie std::vector ähnlich wie ein C-Array verwenden können:

%Vor%

Die Verwendung von std::sort() richtig ist möglich, aber ausführlich, da Sie nicht nur eine Iteratorklasse mit wahlfreiem Zugriff für die Iteration nach Zeilen benötigen, sondern auch eine Klasse, die eine Zeile abstrahiert, sodass std::sort() sie austauschen kann.

Ein anderer Weg, aber trotzdem std::sort zu verwenden, besteht darin, die Elemente, die Sie sortieren wollen, zusammen mit einem Index in ihr eigenes std::vector zu extrahieren. Dann sortiere diesen Vektor und ordne die Reihen in der ursprünglichen Matrix schließlich um die Indizes in diesem Vektor um.

%Vor%     
Grumbel 05.11.2016 13:49
quelle

Tags und Links