qsort und Array



  • Hallo!

    Kann ich mit der Funktion qsort aus den Standardbibliotheken auch ein zweidimensionales Array oder nur ein eindimensionales Array sortieren?
    Als Beispiel: Ich habe eine Tabelle mit "Vorname", "Name", "Land", "Ort" und "Straße". Kann ich diese nun z.B. in erster Instanz nach "Name" und in zweiter Instanz nach "Land" sortieren (also z.B. erst alle Müller aus Deutschland und dann die aus Österreich)?
    Falls mir jemand sagen kann _ob_ das funktioniert, wäre ich sehr dankbar!
    Falls mir jemand sagen kann _wie_ das funktioniert, wäre ich brutalst dankbar! (-:

    Gruß
    Gange



  • Klar, es funktioniert.

    Du kannst ja eine beliebige Vergleichsfunktion angeben.

    Zeig mal, wie Dein Array genau aussieht.

    (Uebrigens, da wir hier schon im C++ Forum sind, hast Du schonmal ueberlegt, ob nicht auch z.B. eine Map aus der STL verwenden kannst? Dann musst Du Deine Daten evtl. ein bisschen umorganisieren, aber im Prinzip wuerde es gehen)



  • qsort ist unter C++ verboten.



  • Wenn Du ein zweidimensionales Array mit char* hast, probier mal folgendes:

    #include <string>
    #include <map>
    
    using std::string;
    using std::multimap;
    using std::pair;
    
    const int Y = 100;
    const int X = 7;
    
    char* myArray[Y][X]; 
    
    void sort( void ) {
       // Annahme, dass myArray vorher korrekt initialisiert wurde
       typedef multimap<string,int>  myMap;
       typedef pair<string,int>      myPair;
       typedef myMap::const_iterator myMapCIter;
       // Map aufbauen: Schluessel -> Zeile
       myMap map;
       int y;
       for ( y=0; y < Y; ++y ) {
          // die ersten zwei Spalten als Sortierkriterium:
          // alle Felder jeder Spalte muessen gleich breit sein
          string key = string( myArray[y][0] ) + string( myArray[y][1] );
          map.insert( myPair( key, y ) );
       }
       // neues, temporaeres Array aufbauen
       char* newArray[Y][X];         
       myMapCIter iter = map.begin();
       y = 0; // neues y
       while ( iter != map.end() ) {
          int old_y = iter->second;
          for ( int x=0; x < X; ++x ) {
             newArray[y][x] = myArray[old_y][x];
          }
          iter++; ++y;
       }
       // Ergebnis zurueckkopieren
       for ( y=0; y < Y; ++y ) {
          for ( int x=0; x < X; ++x ) {
             myArray[y][x] = newArray[y][x];
          }
       }
    }
    

    Die Loesung ist mit Sicherheit nicht die eleganteste, aber es ist eine Loesung! 😉



  • Hallo!

    Erst mal danke für die Antworten!!!
    Das Array hat eine maximale Größe von 5x1000. Die Elemente sehen z.B. so aus:

    [Vorname] [Name] [Wohnort] [Geburtsdatum] [Email-Adresse]

    Es soll nun möglich sein, z.B. in erster Ebene nach Name, in zwieter nach Vorname und in dritter nach Geburtsdatum zu sortieren. In einer der Ebenen evtl auch rückwerts.
    Hat jemand eine Idee wie dann die Compare-Funktion die qsort benötigt aussehen soll?
    PS: Es _muss_ qsort sein 🙂



  • In der Theroie doch so

    int vergleich (a, b){
      int i;
      i = strcmp(a.name, b.name);
      if (i != 0){
        return i;
      } else {
        i = strcmp(a.vorname, b.vorname);
        if (i != 0){
          return i;
        } else {
          i = geburtvergleich(a.geburt, b.geburt);
          return i;
        }
      }
    }
    

    Ist nicht ganz wie dein Array und auch nur Pseudo-Code aber ich denke du verstehst schon.
    geburtvergleich() muss natürlich noch geschieben werden und gleich rückgabesystem haben wie strcmp.



  • Verwende std::sort, ist schneller als qsort 🙂



  • klingt, als solltest Du besser ne

    struct Person
    {
      std::string vorname;
      std::string nachname;
    
      // etc.
    }
    

    bauen. Oder sogar ne class? Hängt vom Anwendungsfall ab...

    Dann ist das Array schonmal eindimensional.
    Dann bauste einen Vergleicher:

    bool compareByNachname(Person const& lhs, Person const& rhs)
    {
      return lhs.nachname < rhs.nachname;
    }
    

    Anschließend genügt ein einfacher Aufruf:

    sort(array, array+anzahlEinträge, compareByNachname);
    

    Und die Sache ist sortiert. Wenn Du ein anderes Sortierkriterium willst mußt Du nur ne andere Vergleichsfunktion schreiben und die dann als Parameter an sort übergeben.

    MfG Jester



  • PS: Es _muss_ qsort sein



  • Oh, übersehen. Da hilft wohl nur eins: Die Aufgabenstellung abändern. 😃



  • Dann ist ja wohl auch Aufgabenstellung, den qsort selber zu schreiben, oder? Amsonsten würde das schließlich keinen Sinn ergeben.



  • Optimizer schrieb:

    Dann ist ja wohl auch Aufgabenstellung, den qsort selber zu schreiben, oder? Amsonsten würde das schließlich keinen Sinn ergeben.

    Hm, ich ging bisher davon aus, daß es sich dabei um die im C-Standard enthaltene qsort-Funktion handelt.



  • Ähm ok, mein Fehler, steht im ersten Post wohl so drin. Natürlich IMHO sinnlos, das vorzuschreiben.



  • Optimizer schrieb:

    Natürlich IMHO sinnlos, das vorzuschreiben.

    Das kommt davon, dass die Aufgabe im Rahmen eines - wie es ja immer heisst - praxisbezogenen FH-Studiums gestellt wurde... 😉


Anmelden zum Antworten