Liste sortieren nach bestimmten Wert



  • Hallo,

    ich hab eine Liste mit Koordinaten. Die Koordinaten sind als Struktur angelegt.

    struct Point3D
    {
      double x;
      double y;
      double z;
    }
    
    int main()
    {
      ...
    
      list<Point3D> myList;
      Point3D myPoint;
    
      ...
    
      sort(myList.begin(),myList.end(),myPoint.x);
    
      ...
    
      return 0;
    }
    

    So kann ich scheinbar nicht nach x sortieren. Wie kann ich es besser machen?

    Danköööö!



  • std::sort benutzt operator< für den Vergleich der Element, diesen gibts aber für deine Struktur nicht.
    Folglich muss du ihn definieren, dh du definierst wie Objekte deiner Struktur vergleicht werden.

    bool operator<(const Point3D& lhs, const Point3D& rhs)
    {
        // dein Vergleichkirterium ;)
    }
    
    sort(..begin(), ..end());
    

    Nun benutzt sort deinen Operator 😉



  • Kannst du vielleicht zu meinem Problem Funktion mal hinschreiben? Wenn ichs einmal sehe dann versteh ich das Prinzip auch. Aber irgendwie komm ich gerad nicht drauf. 😞



  • bool operator<(const Point3D& lhs, const Point3D& rhs)
    {
        return lhs.x < rhs.x;
    }
    


  • Hallo,

    dieser Funktor geht scheinbar nur mit Vektoren. Bei Listen lässt sich dieser nicht anwenden. Wenn jemand weiss warum oder er ne Lösung für Listen hat, einfach hier posten.



  • Mister Wing schrieb:

    dieser Funktor geht scheinbar nur mit Vektoren. Bei Listen lässt sich dieser nicht anwenden.

    Dann machst Du scheinbar etwas falsch.



  • Meine Fresse, die Arroganz, die hier einige raushängen lassen, ist manchmal echt nur schwer zu ertragen.
    Er stellt 'ne Frage, zeigt, dass er was gemacht hat (wenn sowas fehlt, kommt von vielen erstmal immer "zeig' mal was, dann helfen wir") , und trotzdem kommt nur so ein elendiges Gekeife.

    std::sort geht nur auf Random-Access Iteratoren. std::list hat aber bidirektionale Iteratoren. std::list bringt aber seine eigene sort-Funktion mit:

    #include <list>
    
    //...
    MyType
    {
       //...
    };
    
    std::list<MyType> l;
    
    bool compareFieldY(const MyType& left, const MyType& right)
    {
       return left.FieldY < right.FieldY;
    }
    
    //liste ist irgendwie gefuellt worden
    
    l.sort(compareFieldY);
    

    So in etwa.



  • Hallo. Also auch wenn meine antwort etwas trivial ist .Schreibe dir eine Funktion die den Vergleich vornimmt und rufe sie in der sort unktion mit auf !



  • Tachyon schrieb:

    Er stellt 'ne Frage, zeigt, dass er was gemacht hat

    Ich sehe nur die Vermutung, dass der Operator nicht auf Listen funktioniert. Er hätte lediglich die Fehlermeldung des Compilers posten müssen, dann hätte er eine umfassende Antwort erhalten.

    So wird das Kristallkugelverhalten nie ausgerottet.



  • Wie kann ich nach einem zweiten Kriterium ordnen? Meine Lösung sieht bisher so aus. Bei der zweiten Sortierung zerstört er die erste Sortierung. Es soll also erst nach xund dann nach y und dann nach z sortiert werden.

    struct Point3D
    {
      double x;
      double y;
      double z;
    }
    
    struct SortBy_x
    {
      bool operator() (const Point3D& Left, const Point3D& Right)
      {
        return ( Left.x < Right.x );
      }
    };
    
    struct SortBy_y
    {
      bool operator() (const Point3D& Left, const Point3D& Right)
      {
        return ( Left.y < Right.y );
      }
    };
    
    struct SortBy_z
    {
      bool operator() (const Point3D& Left, const Point3D& Right)
      {
        return ( Left.z < Right.z );
      }
    };
    
    int main()
    {
      ...
    
      vector<Point3D> myVector;
    
      //Der Vektor wird gefüllt
      ...
    
      //Dann die Sortierungen
      sort(myVector.begin(),myVector.end(),SortBy_x);
      sort(myVector.begin(),myVector.end(),SortBy_y);
      sort(myVector.begin(),myVector.end(),SortBy_z);
    
      ...
    
      return 0;
    }
    

    Hier bei zersört er mir aber wieder die alte Sortierung. Muss ich die ganzen Sortierkriterien in einem Operator zusammenfassen? Zum Beispiel so hier:

    struct SortBy_xyz
    {
      bool operator() (const Point3D& Left, const Point3D& Right)
      {
        if ( Left.x < Right.x )
          if ( Left.y < Right.y )
            return ( Left.z < Right.z );    
      }
    };
    


  • Ja, musst Du.



  • So, habe jetzt meinen Operator erweitert. Aber was mache ich im letzten Schritt um z zu vergleichen? Bei der Lösung gibt es einen Absturz.

    if ( Left.x == Right.x )
    {
      if ( Left.y == Right.y )
      {
        if ( Left.z == Right.z )
          return true;
        else
          return ( Left.z < Right.z );
      }
      else
        return ( Left.y < Right.y ); 
    }
    else
      return ( Left.x < Right.x );
    


  • Das sollte eigentlich so aussehen.

    if ( Left.x == Right.x )
    {
        if ( Left.y == Right.y )
            return Left.z < Right.z;
        return Left.y < Right.y;
    }
    return Left.x < Right.x;
    

    Einen Absturz sollte aber auch deine Variante nicht verursachen.



  • Was ist mit dem Fall das beide z gleich sind?



  • Wenn alle Elemente gleich sind muß die Funktion false zurückgeben. Es ist schließlich der operator< und nicht der operator==.


Anmelden zum Antworten