Sort() Algorithmus für std::list produziert Fehler, den ich nicht lösen kann



  • #include <iostream>
    #include <list>
    #include <algorithm>
    #include <iomanip>
    
    using namespace std;
    
    class Liga;
    
    class Verein 
    {
    friend class Liga;
    public:
        string name;
        int toreGeschossen;
        int toreKassiert;
        int punkte;
        
    public:
        Verein(string a="N.V.", int b=0, int c=0, int d=0)
            : name(a), toreGeschossen(b), toreKassiert(c), punkte(d)
                {}
        
        bool operator == (const Verein& b) 
        {
            return name==b.name;
        }
        
        bool operator < (const Verein& b)
        {
            return name<b.name;
        }
        
        friend ostream& operator << (ostream& os, Verein& a)
        {
            os << setw(15) << a.name << a.toreKassiert << ":" << a.toreKassiert << "      " << a.toreGeschossen-a.toreKassiert << "     " << a.punkte;
            return os;
        }
        
        friend bool VergleichTordifferenz(const Verein& , const Verein& );
        friend bool VergleichPunkte(const Verein&, const Verein& );
        
    };
    
        bool VergleichTordifferenz(const Verein& a, const Verein& b)
        {
            int a1,a2,b1,b2, dif1, dif2;
            a1= a.toreGeschossen;
            a2= b.toreGeschossen;
            b1= a.toreKassiert;
            b2= b.toreKassiert;
            
            dif1=a1-b1;
            dif2=a2-b2;
            
            return dif1<dif2;
        }
        
        bool VergleichPunkte(const Verein& a, const Verein& b)
        {
            return a.punkte>b.punkte;
        }
    
    
    class Liga
    {
    
    friend class Verein;
    private:
        string name;
        list<Verein> mannschaften;
        
    public:
        Liga(string a, list<Verein> b)
            : name(a), mannschaften(b)
                {}
                
        Liga(string a, Verein b)
            : name(a)
                {mannschaften.push_back(b);}
        Liga(string a)
            : name(a)
                {}
                
        void verein_hinzufuegen(Verein& a)
        {
            mannschaften.push_back(a);
            return;
        }
        
        void verein_entfernen(Verein& a)
        {
            mannschaften.remove(a);
            return;
        }
        
        void sortieren(int a=1)
        {
            if(a==1)
                sort(mannschaften.begin(), mannschaften.end());
            if(a==2)
                sort(mannschaften.begin(), mannschaften.end(), VergleichPunkte);
            if(a==3)
                sort(mannschaften.begin(), mannschaften.end(), VergleichTordifferenz);
            return;
        }
        
        friend ostream& operator << (ostream& os, Liga& a)
        {
            int i{1};
            os << a.name << endl;
            auto end1 = a.mannschaften.end();
            for(auto iterator=a.mannschaften.begin(); iterator!= end1; iterator++)
            {
                cout << i << ".";
                cout << *iterator;
            }
            return os;
        }
        
        
        friend void neueSaison(Liga& a, Liga& b)
        {
            a.sortieren(2);
            auto iter=a.mannschaften.end();
            int d{0}, c{0};
            while(c<2)
            {
                if(iter->punkte==(--iter)->punkte)
                    d++;
                else
                    c++;
            }
            if(d!=0)
            {
                d-=2;
                auto begrenzung1=a.mannschaften.end();
                advance(begrenzung1,d);
                sort(begrenzung1, a.mannschaften.end(), VergleichTordifferenz);
            }
                
            b.sortieren(2);
            auto itera=a.mannschaften.end();
            int e{0}, f{0};
            while(f<2)
            {
                if(itera->punkte>(--itera)->punkte)
                    e++;
                else
                    f++;
            }
            if(e!=0)
            {
                e-=2;
                auto begrenzung2=a.mannschaften.end();
                advance(begrenzung2,e);
                sort(begrenzung2, a.mannschaften.end(), VergleichTordifferenz);
            }
            
            swap(*a.mannschaften.end(), *b.mannschaften.begin()); // *Iterator benutzen.
            auto begrenzung3=a.mannschaften.end();
            advance(begrenzung3, -1);
            auto begrenzung4=b.mannschaften.begin();
            advance(begrenzung4, 1);
            swap(*begrenzung3, *begrenzung4);
            
            
            auto end2=a.mannschaften.end();
            for(auto it=a.mannschaften.begin(); it!=end2; it++) 
            {
                it->punkte=0;
                it->toreGeschossen=0;
                it->toreKassiert=0;
            }
            
            auto end3=b.mannschaften.end();
            for(auto it=b.mannschaften.begin(); it!=end3; it++)
            {
                it->punkte=0;
                it->toreGeschossen=0;
                it->toreKassiert=0;
            }
            return; 
        }
    };
    

    Hier erhalte ich folgenden Fehlercode beim compilieren:

    "In file included from /usr/include/c++/5/algorithm:62:0,
    from fußball.cpp:3:
    /usr/include/c++/5/bits/stl_algo.h: In instantiation of ‘void std::__sort(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = std::_List_iterator<Verein>; _Compare = __gnu_cxx::__ops::_Iter_less_iter]’:
    /usr/include/c++/5/bits/stl_algo.h:4698:18: required from ‘void std::sort(_RAIter, _RAIter) [with _RAIter = std::_List_iterator<Verein>]’
    fußball.cpp: 100:58: required from here
    /usr/include/c++/5/bits/stl_algo.h:1964:22: error: no match for ‘operator-’ (operand types are ‘std::_List_iterator<Verein>’ and ‘std::_List_iterator<Verein>’)
    std::__lg(__last - __first) * 2,"

    Einige Stunden rumprobieren und ich finde den Fehler einfach nicht. Leider müsste wir std::list und dürfen nicht std::vektor benutzen.
    Es wäre echt mega hilfreich, wenn wer den Fehler finden könnte.

    Viele Grüße
    Tristan



  • Ich schau mir sicher keine 180 Zeilen Code an.

    std::sort funktioniert nicht mit std::list, daher hat die eine eigene sort Funktion.



  • @TristanS sagte in Sort() Algorithmus für std::list produziert Fehler, den ich nicht lösen kann:

    bool VergleichTordifferenz(const Verein& a, const Verein& b)
    {
        int a1,a2,b1,b2, dif1, dif2;
        a1= a.toreGeschossen;
        a2= b.toreGeschossen;
        b1= a.toreKassiert;
        b2= b.toreKassiert;
        
        dif1=a1-b1;
        dif2=a2-b2;
        
        return dif1<dif2;
    }
    

    Lass sowas bitte bleiben (außer du willst bewusst jemanden ärgern).

    auto Tordifferenz(Verein const &verein)
    {
        return verein.toreGeschossen - verein.toreKassiert;
    }
    
    bool VergleichTordifferenz(Verein const &a, Verein const &b)
    {
        return Tordifferenz(a) < Tordifferenz(b);
    }
    

    Wieso ist neueSaison() ein friend und kein Member? So oder so, die Funktion ist viel zu lang.



  • Warum list statt vector?

    Das es nicht funktioniert, liegt übrigens darun, dass list keine random-access-iteratoren hat. Daher die von manni erwähnte, eigene sort-funktion für list.



  • @TristanS sagte in Sort() Algorithmus für std::list produziert Fehler, den ich nicht lösen kann:

    Leider müsste wir std::list und dürfen nicht std::vektor benutzen.



  • @Swordfish

    Oh, ok. Was das schon wieder soll...



  • Die Funktion muss friend sein und der Datentyp list, da wir eine vorgegebene Main hatten, aus der dies hervorging.

    Das sort() bei list eine Memberfunktion ist, war der entscheidende Hinweis.
    Also hatte ich noch einmal in die Dokumentation geschaut und direkt den 2. Fehler gefunden, dass die sort-Funktion für list auch keine Parameter für den Sortierbereich nimmt.
    Also musste ich die Liste in 2 teilen, den zu sortierenden Bereich sortieren und beide Listen wieder zusammenfügen.

    Danach funktioniert es, vielen Dank! 🙂



  • @TristanS sagte in Sort() Algorithmus für std::list produziert Fehler, den ich nicht lösen kann:

    Also musste ich die Liste in 2 teilen, den zu sortierenden Bereich sortieren und beide Listen wieder zusammenfügen.

    Ja. std::list<>::splice() ist dein Freund.



  • @Swordfish sagte in Sort() Algorithmus für std::list produziert Fehler, den ich nicht lösen kann:

    @TristanS sagte in Sort() Algorithmus für std::list produziert Fehler, den ich nicht lösen kann:

    bool VergleichTordifferenz(const Verein& a, const Verein& b)
    {
        int a1,a2,b1,b2, dif1, dif2;
        a1= a.toreGeschossen;
        a2= b.toreGeschossen;
        b1= a.toreKassiert;
        b2= b.toreKassiert;
        
        dif1=a1-b1;
        dif2=a2-b2;
        
        return dif1<dif2;
    }
    

    Lass sowas bitte bleiben (außer du willst bewusst jemanden ärgern).

    auto Tordifferenz(Verein const &verein)
    {
        return verein.toreGeschossen - verein.toreKassiert;
    }
    
    bool VergleichTordifferenz(Verein const &a, Verein const &b)
    {
        return Tordifferenz(a) < Tordifferenz(b);
    }
    

    Wieso ist neueSaison() ein friend und kein Member? So oder so, die Funktion ist viel zu lang.

    Jetzt wo du es sagst, hätte ich auch anstatt der Referenz eine Kopie übergeben können und mir das schlecht leserliche umspeichern der Werte sparen können.

    Wie ginge die Funktion kürzer? Es war halt vorgegeben, dass nach Punkten und notfalls nach dem Torverhältnis sortiert, Auf- und Abstieg implementiert wird und die Werte wieder auf 0 gesetzt werden sollen.



  • @TristanS sagte in Sort() Algorithmus für std::list produziert Fehler, den ich nicht lösen kann:

    Jetzt wo du es sagst, hätte ich auch anstatt der Referenz eine Kopie übergeben können und mir das schlecht leserliche umspeichern der Werte sparen können.

    Was meinst Du? VergleichTordifferenz()? Da ist es völlig egal ob Du eine Kopie, eine Referenz oder eine konstante Referenz übergibst, "umspeichern" brauchst Du in keinem der Fälle. Natürlich sollte man aber in der Regel als const & übergeben wenn das übergebene Ding größer ist als ein Zeiger und nicht verändert wird.

    @TristanS sagte in Sort() Algorithmus für std::list produziert Fehler, den ich nicht lösen kann:

    Wie ginge die Funktion kürzer?

    VergleichTordifferenz()? Ist Dir die Version die Du von mir Zitiert hast noch nicht kurz und leserlich genug?

    @TristanS sagte in Sort() Algorithmus für std::list produziert Fehler, den ich nicht lösen kann:

    Es war halt vorgegeben, [...]

    Hast Du eine komplette Aufgabenstellung?


Anmelden zum Antworten