copy algortihmus mit Liste
-
Hallo Leute!
Die Liste ist Private-Member der Klasse Calendar!
Ich hätte mal eine kurze Frage zu folgender Funktion:void Calendar::PrintAllEntries(bool ascending) const{ Print(this->CalendarList, "Ausgabe der Liste mit Algorithm"); } // Hilfsfunktionen für Ausgabe void Print(list<CalendarEntry> const & list, string const & s){ cout << endl << s << endl; copy(list.begin(), list.end(), ostream_iterator<CalendarEntry> (cout, " ")); cout << endl; }Mein Problem ist jetzt aber, dass ich beim Copy algorithmus ja nicht per ostream iterator die Struktur ausgeben kann, sondern eig will ich ja ausgeben:
Struktur.String
Struktur.Datumwie mache ich das jetzt am geschicktesten?

Danke im Vorraus allen Helfern!
-
Ich hab dich so verstanden:
class calender { private: string str; string datum; public: calender(const string& str, const string& datum) : str(str), datum(datum) {} friend ostream& operator<<(ostream& out, const calender& c) { return out << c.str << ','<< c.datum << '\n'; } }; int main() { list<calender> l; l.push_back(calender("string","datum")); l.push_back(calender("string2","datum2")); copy(l.begin(),l.end(),ostream_iterator<calender>(cout)); return 0; }
-
Ah mein Fehler, ich habe eine Info unterschlagen! Bei dem Datum handelt es sich wiederum um ein Unterobjekt mit eigener Printfunktion und Vergleichsfunktion Compare.
Der Vektor soll zuerst nach Objekt "Datum" sortiert werden und danach möglichst elegant mittels Sort-Algorithmus richtig sortiert ausgegeben werden.
Hier mal zum Lesen den Codes des Objektes "Datum", für alle dies interessiert:
// Header #ifndef Date_H #define Date_H #include <iostream> class Date { public: // Default-Constructor Date(); // Constructor Date(int const day, int const month, int const year); //Destruktor ~Date(); // Accessor functions getDay, getMonth, getYear int GetDay() const; int GetMonth() const; int GetYear() const; // Comparison function int Compare(const Date &d) const; // Write date to an output stream void Print(std::ostream &out) const; private: int mDay; int mMonth; int mYear; }; // Output operator inline std::ostream &operator<<(std::ostream &out, Date const &date) { date.Print(out); return out; } #endif// Modul / Default - CTOR anlegen Date::Date() : mDay(0), mMonth(0), mYear(0) { cout << "+++ Objekt mit Adresse: " << hex << this << " erzeugt. +++" << endl; } //CTor MIT Werten Date::Date(int const day, int const month, int const year) : mDay(day), mMonth(month), mYear(year) { cout << "+++ Objekt mit Adresse: " << hex << this << " erzeugt. +++" << endl; } // DTOR Date::~Date() { cout << "+++ Objekt mit Adresse: " << hex << this << " zerstört. +++" << endl; } // Accessor functions getDay int Date::GetDay() const { return mDay; } // Accessor functions getMonth int Date::GetMonth() const { return mMonth; } // Accessor functions getYear int Date::GetYear() const { return mYear; } // Comparison function (returns -1 if current date (this) is before d, +1 if it is after d, 0 if it is equal) int Date::Compare(const Date &d) const { if ( this->mYear < d.mYear) { return -1; } else if (this->mYear > d.mYear) { return 1; } else if (this->mYear == d.mYear){ if (this->mMonth < d.mMonth){ return -1; } else if(this->mMonth > d.mMonth){ return 1; } else if (this->mMonth == d.mMonth) { if (this->mDay < d.mDay) { return -1; } else if (this->mDay > d.mDay) { return 1; } else if (this->mDay < d.mDay){ return 0; } } } return 0; } // Write date to an output stream void Date::Print(std::ostream &out) const { out << "---------------------------------" << endl; out << setfill('0') << setw(2) << dec << mDay << "."; out << setfill('0') << setw(2) << dec << mMonth << "."; out << setfill('0') << setw(4) << dec << mYear << endl; out << "---------------------------------" << endl; }
-
Und hier noch die Klasse kalender:
struct CalendarEntry { std::string Note; Date Datum; }; typedef std::list <CalendarEntry> DataList; typedef std::list<CalendarEntry>::iterator ListIterator; class Calendar { public: // Constructors, Destructor, assignment operator (if necessary) Calendar(); ~Calendar(); // Assignment operator Calendar &operator =(Calendar const &cal); // Adds an entry to the calendar. If an entry for the given date already // exists, it is replaced. void AddEntry(Date const &date, std::string const &text); // Deletes all entries from the calendar void Clear(); // Prints all entries, sorted by their date, either ascending or // descending, depending on the parameter void PrintAllEntries(bool ascending=true) const; private: DataList CalendarList; };
-
So und jetzt NOCH EINMAL mein Problem erläutert!
Ich weiß nicht, wie ich den COPY-ALGORITHMUS anwenden muss / modifizieren muss, damit er funktioniert^^
Das ist mein Problem! ATM so wie ich ihn in der Printfunktion schreibe, funzt das mitm ostream_iterator nicht!
Die Ausgabe auf cout muss ja auf die Strukturunterobjekte erfolgen und nicht auf die struktur selber! Aber der Compiler meckert immer^^
-
Dir fehlt eigentlich nur der Ausgabeoperator für CalendarEntry. Aber der Reihe nach: Zuerst wird mal Date aufgeräumt. Im zweiten Konstruktor sind die const-Qualifizierer bei den Parametern überflüssig, weil die Werte by value übergeben werden. Deine Compare-Funktion ist so kompliziert aufgeschrieben, dass dir nicht mal dein Fehler beim letzten if aufgefallen ist. Ich würde sowieso einen operator< statt Compare definieren, sodass std::sort direkt drauf funktioniert:
bool operator<(const Date& lhs, const Date& rhs) { if(lhs.year != rhs.year) return lhs.year < rhs.year; if(lhs.month != rhs.month) return lhs.month < rhs.month; return lhs.day < rhs.day; }Statt
typedef std::list <CalendarEntry> DataList; typedef std::list<CalendarEntry>::iterator ListIterator;nimmst du besser
typedef std::vector <CalendarEntry> DataList; typedef DataList::iterator ListIterator;Auf diese Weise passt ListIterator immer zum DataList-Container. Außerdem ist std::vector in 99% der Fälle die richtige Wahl, auch wenn dir irgendwelche Theoretiker mal gesagt haben, dass man bei std::list gut einfügen und entfernen kann. Bei vector funktioniert dann auch das Kopieren und Sortieren schnell genug. Dein Ausgabeoperator macht dann so etwas:
DataList calendarCopy(CalendarList); sort(calendarCopy.begin(), calendarCopy.end()); copy(calendarCopy.begin(), calendarCopy.end(), ostream_iterator<CalendarEntry>(out, " "));Edit: Achja, in deiner Print-Funktion änderst du mit Manipulatoren den Zustand des ostream-Objekts. Den Zustand solltest du zu Beginn der Funktion kopieren und beim Verlassen der Funktion zurücksetzen.
-
Hey, schonmal danke für deine Hilfe so weit!
Leider ist in der Aufgabe definiert, dass ich eine Liste verwenden muss, könnte ich frei wählen, hätte ich auch einen Vector verwendet!
Die Compare-Funktion war teilweise auch so vorgegeben, aber deine idee mit dem Operator Owerloading werd ich glatt übernehmen ist viel eleganter

Ich probier mal nachher ein paar Sachen aus und meld mich wieder falls noch fragen auftreten

-
copy(calendarCopy.begin(), calendarCopy.end(), ostream_iterator<CalendarEntry>(out, " "));Eben genau das, dachte ich, dass ich eben NICHT machen darf, weil ich ja keinen CalenderEntry auf der Konsole ausgeben kann, da es sich dabei ja um eine Struktur handelt! So wie ich die Zeile grad verstehe, gibt der doch dann Strukturen auf outstream aus, was ja eigentlich nicht geht oder?^^
will ja eigentlich sukzessive den String und die Printfunktion des Date-Objektes an jeder Stelle der Liste ausgeben!
-
Eteru schrieb:
So wie ich die Zeile grad verstehe, gibt der doch dann Strukturen auf outstream aus, was ja eigentlich nicht geht oder?^^
Klar geht das, wenn du den entsprechenden Operator überlädst.
structist fast dasselbe wieclass, lediglich die Default-Sichtbarkeit (public/private) und Default-Vererbung (public/private) sind verschieden. Schreib also so etwas:ostream& operator<<(ostream& out, const CalendarEntry& entry) { out << entry.Date << " (" << entry.Note << ")"; return out; }
-
Tut mir Leid konnte eine Weile lang nicht ins Internet!
Vielen dank für den Tipp mit dem Operator Owerloading! Hat mein Problem gelöst!
Funktioniert jetzt alles wunderbar!