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.Datum

    wie 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. struct ist fast dasselbe wie class , 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!


Anmelden zum Antworten