Problem mit Listen

Meandor

Grünschnabel
Liebe Leute

habe ein Problem mit verketten Listen ich schicke einfach mal meinen Code

Code:
#include <iostream> 
#include <list> 
using namespace std; 
void Liste_ausgeben(); //Prototyp der Funktion Liste_ausgeben() 
enum STATUS //Definition des Status 
{ 
  AKTIV, GEMELDET 
}; 
class Auftragsliste //Die Klasse der Auftragsliste alles public deklariert 
{ 
public: 
    Auftragsliste(int Wert, double Zeit, STATUS Status) //char status 
    { 
        m_Zeit=Zeit; 
        m_Wert=Wert; 
        m_Status=Status; 
    } 
    double m_Zeit; 
    int m_Wert; 
    STATUS m_Status; //mit enum definiert 
}; 
//globale Variablen deklariert! Damit die Funktion Liste_ausgeben() den iterator kennt; 
list<Auftragsliste*> lAuftrag; 
list<Auftragsliste*>::iterator i; 
int main() 
{ 
    int Anzahl =0; 
    Auftragsliste *Temp = NULL; 
    cout <<"Wie viele Aufträge erzeugen?"<<endl; 
    cin>> Anzahl; 
    for (int j=0; j<Anzahl; j++) 
    {    Temp = new Auftragsliste(1,1,GEMELDET); 
        lAuftrag.push_back (Temp); 
    } 
    Anzahl=0; 
    for (i=lAuftrag.begin(); i!=lAuftrag.end(); ++i) 
    {    cout<<"DAS ELEMENT "<<(*i)->m_Wert<<" wird bei der Zeit :" <<(*i)->m_Zeit<<" der Status : "; 
        if((*i)->m_Status==GEMELDET) 
        cout<<"GEMELDET"<<endl; 
        else 
        cout<<endl; 
    }    cout<<endl; 
    
    for (i=lAuftrag.begin(); i!=lAuftrag.end(); ++i) 
    { 
        (*i)->m_Wert = Anzahl; 
        (*i)->m_Zeit = 500; 
        (*i)->m_Status = GEMELDET; 
        Anzahl ++; 
    } 
    Liste_ausgeben();//Ausgabe der Liste! 
    lAuftrag.insert(lAuftrag.begin(), new Auftragsliste(7,900,GEMELDET)); //Einfügen eines neuen Elementes 
    Liste_ausgeben(); 
    i=lAuftrag.end(); //Iterator zeigt aufs Listenende 
    i--; 
    i--;//Zwei Schritte zurück gehen zeigt jetzt auf das vorletzte Element aus der Liste 

    lAuftrag.erase(i); //Hier wird das vorletzte Element aus der Liste gelöscht 
    cout<<endl; 
    Liste_ausgeben(); //Zur Überprüfung Liste anschauen 
    
    for (i=lAuftrag.begin(); i!=lAuftrag.end(); i++) //Liste aus dem Heap wieder komplett freigeben! 
    { 
        delete (*i); 
        (*i) = NULL; 
    } 
    lAuftrag.clear(); 
    return 0; 
}//main 

void Liste_ausgeben() //Definition der Funktion Liste_ausgeben() 
{ 
    for (i=lAuftrag.begin(); i!=lAuftrag.end(); ++i) 
    {    cout<<"DAS ELEMENT "<<(*i)->m_Wert<<" wird bei der Zeit :" <<(*i)->m_Zeit<<" der Status : "; 
        if((*i)->m_Status==GEMELDET) 
        cout<<"GEMELDET"<<endl; 
    } 
    cout<<endl; 
}

Hätte ich eine verkettet Liste mit <int> und diese kann diese mit dem Befehl sort(); sortiert werden. Also aus 6,4,3,3,2,1,7,1,usw. würde
. 1,1,2,3,3,4,6,6,7, usw...

Das gleich will ich auch für meine Liste nur besteht diese aus mehreren Listenelementen also in etwa so.
Nr, Zeit, Status
1, 500, GEMELDET
2, 500, GEMELDET
3, 900, GEMELDET
4, 700, GEMELDET
5, 400, AKTIV
6, 900, GEMELDET
7, 450, AKTIV
8, 700, AKTIV

jetzt soll die STL einfach mal mir die Arbeit erleichtern und ich schreibe einfach
lAuftragsliste.remove ('AKTIV') //das wäre nur Beispiel damit klappt es nicht.
und schwupps sollen alle Aktiven Elemente aus der Liste gelöscht werden und wenn ich die Liste ausgeben würde erscheinen.

1, 500, GEMELDET
2, 500, GEMELDET
3, 900, GEMELDET
4, 700, GEMELDET
6, 900, GEMELDET

Hätte vielleicht einer eine gute Idee wie man das machen könnte?
Wäre echt toll wenn mir jemand helfen könnte.
Mit bestem Dank
 
Hallo,
schau mal hier:

Code:
#include <iostream>
#include <list>
#include <algorithm>
#include <iterator>

using namespace std;

class ListElement{
    private:
        int nr;
        int zeit;
        string status;

    public:
        ListElement(int nr, int zeit, const string& status) : nr(nr), zeit(zeit), status(status){}

        //brauchen wir fuer das removen
        bool operator==(const ListElement& l){
            return status == l.status;
        }

        //brauchen wir fuers sortieren
        bool operator<(const ListElement& l){
            return nr < l.nr;
        }

        //brauchen wir fuers ausgeben
        friend ostream& operator<<(ostream& cout, const ListElement& toPrint){
            cout << toPrint.nr << "\t" << toPrint.zeit << "\t" << toPrint.status;
            return cout;
        }
};

int main(){
    list<ListElement> l;
    l.push_back(ListElement(4, 500, "GEMELDET"));
    l.push_back(ListElement(5, 500, "AKTIV"));
    l.push_back(ListElement(1, 500, "GEMELDET"));
    l.push_back(ListElement(3, 500, "AKTIV"));
    l.push_back(ListElement(2, 500, "AKTIV"));
    copy(l.begin(), l.end(), ostream_iterator<ListElement>(cout, "\n"));
    l.sort();
    cout << "----------------------------------" << endl;
    copy(l.begin(), l.end(), ostream_iterator<ListElement>(cout, "\n"));
    cout << "----------------------------------" << endl;
    l.remove(ListElement(0,0, "AKTIV"));
    copy(l.begin(), l.end(), ostream_iterator<ListElement>(cout, "\n"));
}

//edit update :)

Gruß

RedWing
 
Zuletzt bearbeitet:
Hallo erstmal danke für das schnelle Beantworten der Frage!

Leider funktioniert dein Code aber nicht direkt!

Erstens benötigt man in der main() zum Schluss noch return 0;
ansonsten Fehlermeldung.

und zweitens irgendwas stimmt noch nicht ganz mit dem Überladen deiner Operatoren
ich kenne mich damit zuwenig aus habe gerade noch in einem Tutorial darüber nachlesen müssen was die Dinger genau machen.

Also meine VC++ 6.0 gibt mir die Fehlermeldung das der erste bool operator für den Status nicht hergeleitet werden konnte

Hier mal die ausgespuckten Warnungen

C:\Programme\Microsoft Visual Studio\MyProjects\CListe2\haupt.cpp(20) : error C2784: 'bool __cdecl std::operator ==(const class std::list<_Ty,_A> &,const class std::list<_Ty,_A> &)' : Vorlagenargument fuer 'const class std::list<_Ty,_A> &' von 'clas
s std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >' konnte nicht hergeleitet werden
C:\Programme\Microsoft Visual Studio\MyProjects\CListe2\haupt.cpp(20) : error C2784: 'bool __cdecl std::operator ==(const class std::istream_iterator<_U,_E,_Tr> &,const class std::istream_iterator<_U,_E,_Tr> &)' : Vorlagenargument fuer 'const class
std::istream_iterator<_U,_E,_Tr> &' von 'class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >' konnte nicht hergeleitet werden
C:\Programme\Microsoft Visual Studio\MyProjects\CListe2\haupt.cpp(20) : error C2784: 'bool __cdecl std::operator ==(const class std::reverse_bidirectional_iterator<_BI,_Ty,_Rt,_Pt,_D> &,const class std::reverse_bidirectional_iterator<_BI,_Ty,_Rt,_Pt
,_D> &)' : Vorlagenargument fuer 'const class std::reverse_bidirectional_iterator<_BI,_Ty,_Rt,_Pt,_D> &' von 'class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >' konnte nicht hergeleitet werden
C:\Programme\Microsoft Visual Studio\MyProjects\CListe2\haupt.cpp(20) : error C2784: 'bool __cdecl std::operator ==(const class std::allocator<_Ty> &,const class std::allocator<_U> &)' : Vorlagenargument fuer 'const class std::allocator<_Ty> &' von
'class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >' konnte nicht hergeleitet werden
C:\Programme\Microsoft Visual Studio\MyProjects\CListe2\haupt.cpp(20) : error C2784: 'bool __cdecl std::operator ==(const class std::istreambuf_iterator<_E,_Tr> &,const class std::istreambuf_iterator<_E,_Tr> &)' : Vorlagenargument fuer 'const class
std::istreambuf_iterator<_E,_Tr> &' von 'class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >' konnte nicht hergeleitet werden
C:\Programme\Microsoft Visual Studio\MyProjects\CListe2\haupt.cpp(20) : error C2784: 'bool __cdecl std::operator ==(const class std::reverse_iterator<_RI,_Ty,_Rt,_Pt,_D> &,const class std::reverse_iterator<_RI,_Ty,_Rt,_Pt,_D> &)' : Vorlagenargument
fuer 'const class std::reverse_iterator<_RI,_Ty,_Rt,_Pt,_D> &' von 'class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >' konnte nicht hergeleitet werden
C:\Programme\Microsoft Visual Studio\MyProjects\CListe2\haupt.cpp(20) : error C2784: 'bool __cdecl std::operator ==(const struct std::pair<_T1,_T2> &,const struct std::pair<_T1,_T2> &)' : Vorlagenargument fuer 'const struct std::pair<_T1,_T2> &' von
'class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >' konnte nicht hergeleitet werden
C:\Programme\Microsoft Visual Studio\MyProjects\CListe2\haupt.cpp(20) : error C2676: Binaerer Operator '==' : 'class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >' definiert diesen Operator oder eine Konvertierung
in einen fuer den vordefinierten Operator geeigneten Typ nicht
C:\Programme\Microsoft Visual Studio\MyProjects\CListe2\haupt.cpp(32) : error C2679: Binaerer Operator '<<' : Kein Operator definiert, der einen rechtsseitigen Operator vom Typ 'const class std::basic_string<char,struct std::char_traits<char>,class
std::allocator<char> >' akzeptiert (oder keine geeignete Konvertierung moeglich)
Fehler beim Ausführen von cl.exe.

CListe2.exe - 9 Fehler, 0 Warnung(en)


Ich kann damit leider nix anfangen. Was mache ich falsch oder fehlen noch ein paar Kleinigkeiten wie return 0; am Ende?

Besten Gruß
Jens
 
Hi.
Meandor hat gesagt.:
Ich kann damit leider nix anfangen. Was mache ich falsch oder fehlen noch ein paar Kleinigkeiten wie return 0; am Ende?
Also, da fehlt kein return 0; am Ende weil das von einem C++ Compiler automatisch hinzugefügt werden muß wenn keins da ist. Jetzt verwendest du allerdings den Visual C++ 6 Compiler und der hat anscheinend damit Probleme.

Inkludiere mal noch den <string> Header in dem Programm, dann sollte das gehen.

Gruß
 
Meandor hat gesagt.:
Erstens benötigt man in der main() zum Schluss noch return 0;
ansonsten Fehlermeldung.
deepthroat hat gesagt.:
Also, da fehlt kein return 0; am Ende weil das von einem C++ Compiler automatisch hinzugefügt werden muß wenn keins da ist.

Sowas passiert dann also wenn sich die Firmen, wie Microsoft nicht an Standards halten
:)
Also hier nochmal der Code der auch unter VC++ laufen sollte:

Code:
#include <iostream>
#include <string>
#include <list>
#include <algorithm>
#include <iterator>

using namespace std;

class ListElement{
    private:
        int nr;
        int zeit;
        string status;

    public:
        ListElement(int nr, int zeit, const string& status) : nr(nr), zeit(zeit), status(status){}

        //brauchen wir fuer das removen
        bool operator==(const ListElement& l){
            return status == l.status;
        }

        //brauchen wir fuers sortieren
        bool operator<(const ListElement& l){
            return nr < l.nr;
        }

        //brauchen wir fuers ausgeben
        friend ostream& operator<<(ostream& cout, const ListElement& toPrint){
            cout << toPrint.nr << "\t" << toPrint.zeit << "\t" << toPrint.status;
            return cout;
        }
};

int main(){
    list<ListElement> l;
    l.push_back(ListElement(4, 500, "GEMELDET"));
    l.push_back(ListElement(5, 500, "AKTIV"));
    l.push_back(ListElement(1, 500, "GEMELDET"));
    l.push_back(ListElement(3, 500, "AKTIV"));
    l.push_back(ListElement(2, 500, "AKTIV"));
    copy(l.begin(), l.end(), ostream_iterator<ListElement>(cout, "\n"));
    l.sort();
    cout << "----------------------------------" << endl;
    copy(l.begin(), l.end(), ostream_iterator<ListElement>(cout, "\n"));
    cout << "----------------------------------" << endl;
    l.remove(ListElement(0,0, "AKTIV"));
    copy(l.begin(), l.end(), ostream_iterator<ListElement>(cout, "\n"));
    return 0;
}

Gruß

RedWing
 
Wau!! Ihr seid ja richtig gut hier!

Klappt ja wie am Schnürchen die Liste! Obwohl mir einige Dinge ziemlich unklar sind warum das alles so klappt.
Code:
1. ListElement(int nr, int zeit, const string& status) : nr(nr), zeit(zeit), status(status){} //dies ist der Konstruktor mittels Initialisierungsliste! Oder nicht?

2.
bool operator==(const ListElement& l)
{
            return status == l.status;
}//Das ist ein Operator aber wie funktioniert der und wo wird der konkret aufgerufen.
//das es Operatoren gibt habe ich schon mal gehört und das man damit ganz tolle Sachen mit machen kann auch gibt es dazu ein gutes Tutorial? Ich will ja hier nicht die ganze Zeit nerven

3.
friend ostream& operator<<(ostream& cout, const ListElement& toPrint)
{
            cout << toPrint.nr << "\t" << toPrint.zeit << "\t" << toPrint.status;
            return cout;
}//Hier gibt es sogar eine Friend Klasse Wahnsinn damit hat man nun die möglichkeit auf die Ostream Variablen einfluss zu nehmen obwohl sie bestimmt als private deklariert sind.
4.
Wie muss ich denn einen solchen Operator umgestalten wenn ich einmal nach der Nummer sortieren will und einmal nach der kleinsten Zeit?

also
4, 500, "GEMELDET
5, 300, "AKTIV"
1, 200, "GEMELDET"
3, 100, "AKTIV"
2, 500, "AKTIV"
----------------------------------------
3,100,"AKTIV"
1,200,"GEMELDET"
5,300,"AKTIV"
2,500,"AKTIV"
4,500,"GEMELDET"
--------------------------------------- //sortiert nach der kleinsten Zeit, wobei bei der. 4.und 5. Zeile egal ist welches vorher in der Liste steht. (Wahrscheinlich in der Reihenfolge wie ich geschrieben habe.
 
Hallo,

zu 1.) Rischtisch :)
zu 2.)
void remove(const T& val);
Removes all elements that compare equal to val. The relative order of elements that are not removed is unchanged, and iterators to elements that are not removed remain valid. This function is linear time: it performs exactly size() comparisons for equality.
Da wir der Methode remove ein ListelElement übergeben muss der operator== auch für
dieses Überladen werden, damit die Methode remove einen Kriterium hat um das zutreffende
ListElement zu entfernen

zu 3.)
da wir mithilfe eines ostream_iterators und der Methode copy das ListenElement augeben
wollen muss ein solcher Operator existieren:
Code:
ostream& operator<<(ostream& cout, const ListElement& toPrint)
Somit ist der Operator<< für das ListElement überladen und ich kann entweder mit:
Code:
ListElement l(0,0, "AKTIV");
cout << l;
das ListElement l ausgeben
oder mit:
Code:
copy(l.begin(), l.end(), ostream_iterator<ListElement>(cout, "\n"));
eine komplette Liste von ListElementen ausgeben...
Außerdem muss das Überladen des operators<< global passieren, mit dem Schluessel-
wort friend hat man dann wie du schon richtig erkannt hast Zugriff auf die privaten
Members der Klasse ListElement...

zu 4.)
void sort();
Sorts *this according to operator<. The sort is stable, that is, the relative order of equivalent elements is preserved. All iterators remain valid and continue to point to the same elements. [6] The number of comparisons is approximately N log N, where N is the list's size.

Also:

Code:
        //brauchen wir fuers sortieren
        bool operator<(const ListElement& l){
            return zeit< l.zeit;
        }

Gruß

RedWing
 
Zurück