C++ Sprache - Seite 2

Neue Frage »

Auf diesen Beitrag antworten »
as_string

Ich kanns im Moment wieder nur überfliegen. Später dann mehr.
Da Du ein Array belegst, musst Du es mit "delete[] m_entries;" freigeben. Schau Dir dazu mal z. B. das hier an:
https://de.m.wikibooks.org/wiki/C%2B%2B-...nd_Array-delete
Zum Sortieren hab ich Dir doch schon geschrieben, wie Du das machen sollst. Entweder liest Du nicht wirklich, was ich schreibe, oder Du verstehst den größten Teil nicht. Aber wenn das so wäre, dann frag doch bitte konkret nach!
Wenn Du schon so 10 Termine im Array hast und dann einen hinzufügen sollst, dann kannst Du ja davon ausgehen, dass die 10 alten Termine im alten Array schon sortiert sind. Es wurde ja jeder einzeln eingefügt und Du hast Dich immer darum gekümmert, dass nach dem Einfügen das Array wieder sortiert war.
Jetzt stell Dir vor Du hast eine Liste mit chronologisch schon richtig sortierten Terminen und bekommst einen neuen zum Einsortieren. Da musst Du doch jetzt kein Bubblesort oder sonst einen Sortieralgorithmus machen! Du gehst einfach über das alte, schon sortierte Array und fügst das neue Element an der korrekten Stelle ein. Schon hast Du wieder ein sortiertes Array, fertig. Ich habe Dir doch schon beschrieben, wie Du das machen sollst. Du kannst das dann machen, wenn Du so wie so schon dabei bist das Array umzukopieren.
Letztlich ist das eine kleine Art eines Mergesort, wenn Du unbedingt den Namen eines Sortieralgorithmus verwenden willst...

Gruß
Marco
 
Auf diesen Beitrag antworten »
Victor

Ich versuche es jetzt bisschen zu proggen aber verstehe nicht so richtig wie ich es machen soll Wink
Fällt mir so schwer
[cpp]
Calendar& operator+=(const CCalendarEntry& entry){

CCalendarEntry * oldEntries = m_entries; // das alte Array
CCalenderEntry * newEntries = new CCalendarEntry [m_numberofEntries + 1];
m_entries = newEntries; // m_entries auf das neue Array zeigen lassen
delete [] oldEntries; // das alte Array zerlegen


if(m_entries> CCalendarEntry [m_numberofEntries + 1]){


}



}[/cpp]



Ich will das wenn man dass m_entries grösser ist als das andere Array ,dass das m_entries dann davor steht ?

Aber wie soll ich das machen ?

Ich verpeile gerade total.

Mir fällt das proggen einfach zu schwer traurig
Auf diesen Beitrag antworten »
as_string

Hallo!

Naja, für einen Anfang ist das ja schonmal gar nicht sooo schlecht...
Allerdings brauchst Du eigentlich das oldEntries nicht. Lass doch einfach die Membervariable m_entries noch auf das alte Array weiter zeigen, bis Du das alte Array nicht mehr brauchst. Dann kannst Du es mit delete[] m_entries; löschen und die Variable m_entries auf das neue Array zeigen lassen.

Ich würde also so anfangen:
code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
CCalendar& CCalendar::operator+=(const CCalendarEntry& entry) {
	CCalendarEntry *newEntries = new CCalendarEntry[m_numberOfEntries + 1]();

// ab hier dann das Umkopieren der alten Entries und richtige Einfügen des neuen Entry
// hier also noch ganz viel Code, der die eigentliche Arbeit erledigt

	if(m_entries != nullptr)
		delete[] m_entries;
	++m_numberOfEntries;
	m_entries = newEntries;
	return *this;
}

Der Mittelteil macht also erst noch die ganze Arbeit. Der Code hier macht quasi nur "die Verwaltung". Bis jetzt wäre das neue Array zwar schon im Speicher angelegt, aber noch nicht mit Werten gefüllt. Bis jetzt würden noch alle alten Kalendereinträge und auch der neue einfach verloren gehen.
Du musst jetzt mit einer Schleife über das alte Array laufen, immer ein Element vom alten in das neue Array kopieren, dabei aber schauen, ob der übergebene entry vor dem als nächstes zu kopierende entry aus dem alten Array liegt. Wenn das der Fall ist, muss einmal der neue entry eingefügt werden und dann erst weiter kopiert werden. Wenn der neue entry am Ende dieser Schleife noch nicht eingefügt wurde, dann muss er an das Ende des neuen Arrays kopiert werden.

Kannst Du mal so eine Schleife versuchen?

Gruß
Marco

PS: Hier noch meine Header-Datei. Ich hab sie allerdings nicht von Eclipse generieren lassen sondern von Hand geschrieben, kann also unterschiedlich aussehen.
code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
#ifndef MYCODE_CCALENDAR_H_
#define MYCODE_CCALENDAR_H_

#include "CCalendarEntry.h"
#include "CJulianDate.h"

class CCalendar {
  private:
	CCalendarEntry *m_entries = nullptr;
	unsigned int m_numberOfEntries = 0;

  public:
	CCalendar();
	~CCalendar();

	CCalendar &operator+=(const CCalendarEntry& entry);
	void print() const;
	void print(const CJulianDate& from) const;
};

#endif /* MYCODE_CCALENDAR_H_ */
Auf diesen Beitrag antworten »
Victor

Wieso hast du jetzt nullptr erstellt ?

Kannst du mir das erklären ?
 
Auf diesen Beitrag antworten »
as_string

Naja, nullptr sollte man bei modernerem C++ verwenden. Es ist nur ein Schlüsselwort, ich habe da nichts "erstellt".
Du kannst natürlich auch die Zahl 0 oder NULL nehmen, aber beides lässt sich eben dann auch wirklich als Zahl verwenden, wohingegen bei nullptr der Compiler meckert, wenn es nicht als Zeiger verwendet wird. Das fängt dann schon ein paar potentielle Fehler zur Compile-Zeit ab.

Gruß
Marco
Auf diesen Beitrag antworten »
Victor

Ich fang mal ganz leicht an :

Soll die for schleife etwa so aussehen?

for(m_entries = 0 ; m_entries>0; m_entries++) {


}

Ist die for schleife so etwa richtig ?
Auf diesen Beitrag antworten »
Victor

ob der übergebene entry vor dem als nächstes zu kopierende entry aus dem alten Array liegt. Wenn das der Fall ist, muss einmal der neue entry eingefügt werden und dann erst weiter kopiert werden
code:
1:
2:
3:
4:
5:
6:
7:
if( m_entries> newEntries){

m_entries == newEntries;

return *this;
}


Würde das so passen ?

Wenn das alte mentries grösser als der neue Entrie Wert ist , wird der alte in den neuen Kopiert und sozusagen davor gestellt .

Mache ich das jetzt auch mit dem Code ? großes Grinsen
Das ist die Frage
Auf diesen Beitrag antworten »
as_string

Zitat:
Original von Victor
Ich fang mal ganz leicht an :

Soll die for schleife etwa so aussehen?

for(m_entries = 0 ; m_entries>0; m_entries++) {


}

Ist die for schleife so etwa richtig ?

Schau Dir bitte nochmal an, wie man über ein Array mit einer for-Schleife iteriert. Du musst eine Zähl-Variable verwenden. m_entries ist aber das Array selbst.
Außerdem m_entries>0? Was soll das denn bezwecken?

Aber ja, eine for-Schleife wäre erstmal der richtige Ansatz (oder ein möglicher zumindest).

Gruß
Marco
Auf diesen Beitrag antworten »
as_string

Zitat:
Original von Victor
ob der übergebene entry vor dem als nächstes zu kopierende entry aus dem alten Array liegt. Wenn das der Fall ist, muss einmal der neue entry eingefügt werden und dann erst weiter kopiert werden
code:
1:
2:
3:
4:
5:
6:
7:
if( m_entries> newEntries){

m_entries == newEntries;

return *this;
}


Würde das so passen ?

Wenn das alte mentries grösser als der neue Entrie Wert ist , wird der alte in den neuen Kopiert und sozusagen davor gestellt .

Mache ich das jetzt auch mit dem Code ? großes Grinsen
Das ist die Frage

Nicht das m_entries ist größer oder kleiner als das neue, sondern einzelne Elemente des m_entries-Arrays sind chronologisch früher oder später als der neu hinzu gekommene Entry.
Ich weiß nicht, ob Du das schon richtig verstanden hast: Die Methode bekommt ein neues Element übergeben, das an der richtigen (chronologischen) Position in das (eventuell) schon vorhandene m_entries-Array einsortiert werden soll.

Das if muss deshalb auch in die Schleife rein, weil Du ja in der Schleife alle m_entries Elemente durch gehst und jedes einzelne musst Du mit dem neuen vergleichen (naja, bis Du halt eines gefunden hast, das chronologisch nach dem neuen entry liegt).

Zeile 3 verstehe ich aber überhaupt nicht: Erstens ist ein doppeltes Gleichheitszeichen ein Vergleichsoperator (also ein Test auf Gleichheit, wie auch immer definiert). Das Ergebnis eines solchen Vergleichs ist true oder false (also bool) und kann in einem if() z. B. verwendet werden.
Falls es eine Zuweisung sein soll, dann musst Du ein einzelnes Gleichheitszeichen verwenden. Aber was Du hier ja willst ist den neuen Eintrag einem Platz im neuen Array zuzuweisen, falls das eingefügt werden soll, ansonsten aber einen eventuell alten Eintrag ins neue Array kopieren.

Gruß
Marco
Auf diesen Beitrag antworten »
Victor

So besser ?

code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
for( m_numberofEntries= 0 ;  m_numberofEntries>0; m_numberofEntries++) {
if( m_entries> newEntries){

m_entries = newEntries;

return *this;
}

}




Ich peile es net was für eine Bedingung ich da einbauen soll? Zunge raus
Auf diesen Beitrag antworten »
as_string

Nicht wirklich besser, würde ich sagen...
Du rätst doch nur rum, das bringt doch keinen wirklich weiter, oder?

In der Aufgabe ist doch schon erwähnt, dass Ihr das entsprechend der Übung mit einem dynamischen Array mit growthSize = 1 entspricht. Den Quelltext von dieser Übung solltest Du ja wahrscheinlich (im Gegnsatz zu mir) haben, oder? Orientiere Dich doch einfach ersteinmal daran. Dann hast Du zwar die Sortierung noch nicht, aber wenigstens schon eine Basis, für die Du sogar schon Punkte bekommen würdest.

Ansonsten zur Sortierung:
Angenommen jemand gibt Dir zwei Notizblöcke. Der eine ist schon voll geschrieben und zwar so, dass auf jedem Blatt ein Termin (mit Datum, Ort, Beschreibung und so steht). Jedes einzelne Blatt ist auch schon mit jeweils einem Termin beschrieben. Die Termine sind so eingetragen, dass der füheste auf dem ersten Blatt steht, dann chronologisch aufsteigend sortiert auf jeden Blatt dann der nächste.
Der andere Block ist leer, hat aber genau ein Blatt mehr als der voll geschriebene.

Außerdem gibt er Dir noch einen extra Zettel, auf dem noch ein weiterer Termin drauf steht, der irgendwo in der Mitte der bisherigen Termine liegen könnte, vielleicht aber auch am Ende oder Anfang, Du weißt es noch nicht.

Deine Aufgabe ist es jetzt alle Termine vom alten in das neue Büchlein zu übertragen, dazu aber auch den neuen einzufügen, und zwar genau so, dass danach wieder alle Termine in der richtigen chronologischen Reihenfolge im neuen Büchlein stehen.

Wie würdest Du vorgehen?
Also ich würde die erste Seite vom alten Block aufschlagen und die erste vom neuen. Dafür brauchst Du eine Index-Variable, oft nimmt man i dafür. Dafür kannst Du nicht m_numberOfEntries nehmen! In dieser Variablen steht ja die Seitenzahl des alten Blocks drin. Wenn Du die Variable mit 0 initialisieren würdest, wäre die Information ja weg! Du musst also eine Schleife z. B. so beginnen:
code:
1:
for(int i = 0; i < m_numberOfEntries; i++) {...}

So, Du hast also die erste Seite aufgeschlagen. Was machst Du jetzt? Je nachdem, ob Dein neuer Termin vor dem ersten Termin im alten Block liegt oder nicht, musst Du ja jetzt entweder den ersten Termin im alten Block auf die erste Seite des neuen abschreiben, oder aber vorher noch den neuen Termin und auf die nächste Seite erst den Termin aus dem alten Block, oder?
Angenommen der erste Termin im alten Block wäre noch vor dem neuen Termin gewesen, dann schreibst Du erst den Termin aus dem alten Block ab, hast aber den neuen Termin noch nicht eingefügt. Also gehst Du weiter zur zweiten Seite vom alten und vom neuen Block.
Hier geht es wieder los: Du musst jetzt dem Termin auf der zweiten Seite mit dem neuen Termin vergleichen, um entschreiden zu können, ob Du gleich den Termin von der zweiten Seite vom alten Block abschreiben musst oder ob Du vorher noch den neuen Termin eintragen musst.

Wenn Du irgendwann den neuen Termin eingetragen hast, weil er früher war als einer der Termine im alten Block, dann ändert sich die Situation etwas: Erstens hast Du ja jetzt den neuen schon eingefügt, also musst Du kein Datum mehr vergleichen und auch keinen weiteren neuen mehr einfügen (ist ja nur einer gewesen). Allerdings ändert sich noch etwas wichtiges: Wenn Du im alten Block auf Seite i bist, im neuen Block aber den neuen Termin schon eingefügt hast, dann bist Du im neuen Block ja immer schon eine Seite weiter, also auf i+1. Sprich: Sobald Du den neuen schon eingefügt hast, musst Du beim kopieren nichtmehr von Seite i vom alten Block auf Seite i vom neuen kopieren, sondern von Seite i vom alten auf Seite i+1 vom neuen.

Das alles muss logischerweise innerhalb der Schleife passieren: Du musst ja jeden Termin vom alten Block mit dem neuen Vergleichen, bis Du die Stelle findest, an der Du korrekt den neuen einfügen kannst.

Also: Schau Dir die Übung mit dem dynamischen Array bitte nochmal an, oder kopier den Quelltext auch hier rein. Versuche mal zuerst genau identisch dazu die Termine zu kopieren, ungeachtet der Sortierung.
Wenn das geklappt hat, lies Dir meine Beschreibung zur Sortierung hier nochmal durch und versuche wirklich ersteinmal nachzuvollziehen, wie Du das "von Hand" mit Notizbüchern machen würdest. Das musst Du zuerst wirklich richtig verstanden haben, sonst bringt es nichts mit Programmieren anzufangen. Falls Du fragen zum dynamischen Array und wie man das auf diesen Kalender hier anwendet hast oder irgendetwas mit dem Sortieren von der Logik her unklar ist, frag bitte konkret die Punkte nach, die Du nicht verstehst.
Ich will Dich ja nicht demotivieren, aber so wie ich das sehe hast Du einen riesigen Aufholbedarf, wenn diese Aufgabe das ist, was Du eigentlich können solltest. Du musst also wirklich die Zähne zusammen beißen. Versuch mal wirklich so vorzugehen, wie ich es geschrieben habe. Ich versuche gerne Dir zu helfen, aber das ist eben über ein Internetforum wirklich schwierig, weil wohl doch einige Grundlagen auch fehlen.

Gruß
Marco
Auf diesen Beitrag antworten »
as_string

Zitat:
Original von as_string
code:
1:
for(int i = 0; i < m_numberOfEntries; i++) {...}


i sollte besser auch als unsigned int deklariert werden, weil m_numberOfEntries unsigned ist.
Also besser:
code:
1:
for(unsigned int i = 0; i < m_numberOfEntries; i++) {...}


Gruß
Marco
Auf diesen Beitrag antworten »
Victor

Kannst du mir erstmal erklären wie z.B der neue Termin heisst und wie der vom alten Block ? großes Grinsen

Das würde mir erstmal auch sehr weiter helfen großes Grinsen
Auf diesen Beitrag antworten »
as_string

Versteh ich nicht, haben die Termine einen Namen?

Gruß
Marco
Auf diesen Beitrag antworten »
Victor

Ja aber ich muss ja auch in der auf Bedingung den alten mit dem neuen Wert vergleichen ?
Wie heißen die beiden ?
Auf diesen Beitrag antworten »
as_string

Ich verstehe immer noch nicht genau, was Du meinst.
Ein Termin (CCalendarEntry) besteht aus drei Feldern, dem Datum und Ort und einer Beschreibung. Wenn Du die Termine chronologisch sortiert haben willst, welches dieser drei Felder wirst Du dann vergleichen müssen?
Um an ein Feld dran zu kommen, hat diese Klasse drei sogenannte "getter-Methoden", für jedes Feld eine. Welche musst Du also verwenden, um an das richtige Feld der beiden Termine dran zu kommen?

Hast Du Dir inzwischen mal die Übung zum "dynamischen Array" nochmal angeschaut? Hast Du eine Idee, wie Du das hier verwenden kannst?

Gruß
Marco
Auf diesen Beitrag antworten »
Victor

Diese Klausr ist von einem alten Semster .

Diese Übung habe ich nicht großes Grinsen

Ich denke mal das ich die Datum vergleichen muss?
Auf diesen Beitrag antworten »
Victor

code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
Calendar& operator+=(const CCalendarEntry& entry){

	CCalendarEntry * oldEntries = m_entries;  // das alte Array
	CCalenderEntry * newEntries = new CCalendarEntry [m_numberofEntries + 1];
	m_entries = newEntries;  // m_entries auf das neue Array zeigen lassen
	delete [] oldEntries;  // das alte Array zerlegen
	for(unsigned int i = 0; i < m_numberOfEntries; i++) {

	if(m_date> CCalendarEntry [m_numberofEntries + 1]){
		weiter immer noch keine Ahnung ?
				
				Ein kleiner tipp nochmals?
		
		


	}
	}


Auf diesen Beitrag antworten »
as_string

Zuersteinmal kannst Du das delete[] ja nicht schon machen, bevor Du die alten Einträge umkopiert hast. Das muss also unter die for-Schleife!
Dann hat die Klasse CCalendar doch gar kein Member m_date. In welcher Klasse ist das definiert? Von welchem Objekt musst Du das Datum mit welchem anderen Objekt-Datum vergleichen?

Irgendwie verstehe ich diese ganze Situation nicht. Es kann doch nicht sein, dass Dir eine solche Aufgabe gestellt wird, wenn Du nicht schon vorher irgendetwas dazu gelernt hattest. Was ist das genau? Eine Vorlesung? Hast Du die ganze Zeit nichts gemacht dafür und jetzt fällt Dir auf, dass Du doch noch etwas abgeben musst?
Ich will Dir da keine Vorwürfe machen... muss ja jeder selbst wissen. Ich versuche es nur zu verstehen. Ich habe einfach den Eindruck, Du verstehst wirklich überhaupt nicht, von was die Rede ist, und rätst nur wild rum. Ich finde einfach, das bringt so ziemlich überhaupt gar nichts...
Ich meine schon das "CCalendarEntry [m_numberofEntries + 1]" von Dir da oben. Erstens ist CCalendarEntry eine Klasse und logischerweise nicht das Array. Welche Variablen zeigen alle auf ein Array? Du weißt ja offensichtlich überhaupt gar nicht, wie man mit Arrays umgeht, etc.
Dann das "m_numberofEntries + 1" in der eckigen Klammer. Erstens ist schon die Variable falsch geschrieben, das "O" von "Of" muss nämlich ein Großbuchstabe sein. Aber das ist gar nicht das Problem: Du willst ja über jedes Element des alten Arrays laufen und hast dazu ja die Index-Variable i eingeführt. Die musst Du jetzt natürlich auch benutzen, um auf die Elemente des Arrays zuzugreifen.
Was sollte denn m_numberOfEntries + 1 überhaupt sein? Das ist doch bei jedem Schleifen-Durchlauf immer derselbe Wert. Und der liegt sogar noch außerhalb des alten und des neuen Arrays.
Das ist das nächste Problem: Du hast offenbar sogar Probleme mit so grundlegenden Dingen wie eine for-Schleife zu verwenden geschweige denn über ein Array zu iterieren.
Das sind ganz elementare Dinge! Es kann nicht sein, dass Ihr vorher so etwas nicht schon irgendwo und irgendwie gelernt habt, bevor Ihr so eine Aufgabe bekommt!

Versteh mich nicht falsch, ich will Dich ja nicht beschimpfen oder Vorwürfe machen... Aber ich bin wirklich verzweifelt und weiß nicht, wie wir das weiter machen sollen. Ich meine eben, so macht das nicht wirklich viel Sinn, oder? Letztlich kann ich Dir auch einfach meine Lösung geben, dann hast Du zwar auch nichts dabei gelernt, aber immerhin sind wir dann irgendwann durch.

Oder aber wir fangen wirklich bei den Basics an. Aber ob das besonders sinnvoll ist, über so ein Forum das alles nachholen zu wollen... ich weiß nicht...

Was meinst Du dazu? Hast Du vielleicht jemanden, mit dem Du Dich mal regelmäßig für ein paar Stunden zusammen setzen könntest um solche Basics mal durchzugehen? Oder sollen wir hier weiter machen? Aber auf diese Art weiter zu machen halte ich für nicht besonders sinnvoll, oder?

Gruß
Marco

PS: Wirklich nicht böse gemeint...
Auf diesen Beitrag antworten »
Victor

Leider habe ich niemanden der mir da helfen kann , daher hatte ich versucht über Forum zu lernen großes Grinsen

Dieser Aufgabenteil war auch gedacht um eine gute Note zu erreichen in der Klausur .
Mir geht es eigentlich nur um das bestehen .

großes Grinsen

Es ist nur ne alte Klausur mehr nicht .
Auf diesen Beitrag antworten »
as_string

mmh, ich weiß halt wirklich nicht, wie ich Dir am ehesten helfen kann. Ich schicke Dir einfach mal, wie ich es programmiert habe, aber wir müssen das dann noch zusammen durch sprechen, damit Du überhaupt etwas davon hast. Normalerweise mache ich das nicht, weil es eigentlich nicht viel nutzt, weder Dir noch mir. Aber ich weiß sonst wirklich nicht, wie wir sonst irgendwie voran kommen sollen.
Hier mal mein Vorschlag für die CCalendar.cpp:
code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
#include "CCalendar.h"
#include "CCalendarEntry.h"
#include "CJulianDate.h"

CCalendar::CCalendar(){}
CCalendar::~CCalendar() {
	if(m_entries != nullptr)
		delete[] m_entries;
}

CCalendar& CCalendar::operator+=(const CCalendarEntry& entry) {
	CCalendarEntry *newEntries = new CCalendarEntry[m_numberOfEntries + 1]();
	bool alreadyInserted = false;
	for(unsigned int i = 0; i < m_numberOfEntries; i++) {
		if(!alreadyInserted && (entry.getDate() < m_entries[i].getDate())) {
			newEntries[i] = entry;
			alreadyInserted = true;
		}
		newEntries[alreadyInserted ? i + 1 : i] = m_entries[i];
	}
	if(!alreadyInserted)
		newEntries[m_numberOfEntries] = entry;

	if(m_entries != nullptr)
		delete[] m_entries;
	++m_numberOfEntries;
	m_entries = newEntries;
	return *this;
}

void CCalendar::print() const{
	cout << "Einträge im Kalender:" << endl;
	for(unsigned int i = 0; i < m_numberOfEntries; i++) {
		m_entries[i].print();
	}
}


Also zuerst merke ich mir, ob denn der neue Eintrag schon eingefügt wurde oder nicht in einer Boolschen Variablen alreadyInserted. Ich muss das mir merken, weil ich den Eintrag ja nur einmal machen darf, allerdings wenn ich durch das ganze alte Array durch gelaufen bin aber noch keinen Eintrag gefunden habe, der nach dem neuen stattfindet, sprich der neue ist der späteste (oder auch einzige bisher), dann muss ich den ja noch ans Ende einfügen.
Ich kopiere das m_entries nicht in ein oldEntries um. Für was? Ich kann doch die m_entries noch so lange auf das alte zeigen lassen, bis ich es abgearbeitet habe und dann das alte löschen, bevor ich m_entries das neue zuweise.
In meiner if()-Bedingung muss ich aber nicht nur das Datum vergleichen, sondern auch schauen, ob ich nicht schon vielleicht vorher den neuen entry schon eingefügt habe. Wenn das der Fall war, brauche ich nicht mehr zu vergleichen.
Zeile 19 ist vielleicht noch kompliziert: Das ist das kopieren eines Eintrags vom alten Array in das neue. Allerdings ist die Position im neuen Array abhängig davon, ob ich schon den neuen Eintrag eingefügt habe oder nicht. So lange ich den alten noch nicht eingefügt habe, muss ich von Position i im alten Array nach Position i im neuen kopieren. Wenn ich aber ins neue Array schon den neuen Eintrag dazwischen geschoben habe, muss ich vom alten Array von Position i auf die Position i+1 im neuen Array kopieren, weil im neuen ja schon ein Eintrag mehr ist als im alten.

Nach der Schleife schau ich, ob nun entry auch schon eingefügt wurde oder nicht, indem ich alreadyInserted nochmal überprüfe. Falls das noch nicht passiert ist, muss ich jetzt entry an die letzte Position im neuen Array kopieren.
Danach kann ich das alte Array löschen (falls überhaupt schon eines vorhanden war) und dem Zeige m_entries das neue aufgebaute Array zuweisen und bin im Großen und Ganzen fertig, wenn ich noch m_numberOfEntries um eins erhöhe.

Versuche das mal wirklich komplett zu verstehen und frage nach, wenn etwas unklar ist. Das ist nur ein Vorschlag für eine Implementierung. Man könnte ein paar Sachen eventuell noch anders lösen, vielleicht eleganter, flexibler oder auch performanter.
Klarer wäre es eventuell, wenn man zwei Index-Variablen i und j eingeführt hätte, wobei i auf die Stelle im alten Array zeigt und j auf die im neuen. Dabei ist i und j gleich, so lange der neue Eintrag noch nicht eingefügt wurde aber j eins größer, sobald er eingefügt ist. Das würde dann auch die Boolsche Variable alreadyInserted ersetzen, würde dann aber auch wieder aufs selbe raus kommen. Vorteil wäre allerdings: Wenn man das ganze noch weiter erweitern wollte und ein ganzes Array von neuen Terminen einfügen wollte, braucht man so wie so mehrere laufende Indizes und so wäre es dann eventuell besser erweiterbar. Aber das war hier ja auch gar nicht verlangt...

Gruß
Marco
Auf diesen Beitrag antworten »
Victor

Ich habe mir noch nicht deinen obigen Beitrag durchgelesen .

Ich hatte nur teilweise eine Idee gehabt

code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
Calendar& operator+=(const CCalendarEntry& entry){

    CCalendarEntry * oldEntries = m_entries;  // das alte Array
    CCalenderEntry * newEntries = new CCalendarEntry [m_numberofEntries + 1];
    m_entries = newEntries;  // m_entries auf das neue Array zeigen lassen
    delete [] oldEntries;  // das alte Array zerlegen
    for(unsigned int i = 0; i < m_numberOfEntries; i++) {

    if( CCalendarEntry [i]   >CCalendarEntry [i+ 1]){
        
        CCalendarEntry [i] = CCalendarEntry [i+ 1];
        
        CCalendarEntry [i+ 1]= new Entries;




    }
m_entries = newEntries;  // m_entries auf das neue Array zeigen lassen
    delete [] oldEntries;  // das alte Array zerlegen

    } 





Das sind teilweise Ideen .

ich weiss das der Code nicht komplett ist .

Macht das ein wenig Sinn?
Auf diesen Beitrag antworten »
Victor

Habe jetzt den insertion Sort Algorithmus genommen und versucht anzuwenden :

code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:


Calendar& operator+=(const CCalendarEntry& entry){

	
	CCalendarEntry * newEntries = new CCalendarEntry [m_numberofEntries + 1];
	unsigned int i,temp,j,m_numberofSize;
	for(i=1; i<m_numberofSize; i++){
		
		temp = CCalendarEntry[i];
		j= i-1;
		while(j>=0 && CCalendarEntry[j]< temp){
			CCalendarEntry[j+1] = CCalendarEntry[j];
			j--;
			
		}
		CCalendarEntry[j+1]= temp;
		}
		
	}



	}
	}



Wie sieht es jetzt aus string ?

Bisschen besser ?

Oder wieder quatsch? großes Grinsen
Auf diesen Beitrag antworten »
as_string

Ich habe das Gefühl, Du hast von dem, was ich geschrieben habe, gar nichts begriffen, oder vielleicht auch einfach gar nicht gelesen...
Statt dessen versuchst Du es mit trial-and-error. Das wird nicht weiterhelfen...
Auf diesen Beitrag antworten »
Victor

Nicht mal teilweise richtig ?
Schade .Ich wollte selbst auf die Lösung kommen .
Auf diesen Beitrag antworten »
as_string

Ja, das ist ja ein schönes Ziel, aber ich denke, Du gehst das komplett falsch an.
Du musst doch ersteinmal die ganzen Basics lernen, bevor Du sinnvoll an so eine Aufgabe überhaupt ran gehen kannst.
Wenn Du z. B. schreibst: "CCalendarEntry[i]" Was soll das denn überhaupt bedeuten? CCalendarEntry ist eine Klasse. Offenbar willst Du aber auf ein Element irgendeines Arrays zugreifen mit dem "[i]". Aber dann musst Du vorne dran auch den Namen des Arrays und nicht den der Klasse schreiben.
Ich weiß nicht, ob Dir so richtig klar ist, was eine Klasse ist, was ein Objekt ist und was ein Array von Objekten ist. Ich denke, wir sollten vielleicht zuerst da anfangen das zu klären.

Aber ich hatte oben ja schon gesagt: Du brauchst keinen speziellen Sortieralgorithmus! Du hast ein schon sortiertes Array und willst in dieses an die richtige Stelle einen neuen Eintrag einfügen. Dafür brauchst Du doch nicht das komplette Array sortieren, sondern es genügt, beim ohnehin notwendigen Umkopieren das neue Element zum richtigen "Zeitpunkt" dazuwischen zu schieben.
Weil ich das schon geschrieben habe und auch ausführlich das Vorgehen erklärt habe, verstehe ich einfach nicht, warum Du jetzt wieder mit einem Sortieralgorithmus kommst. Warum schreibe ich dann überhaupt solche Romane? Und um das zu verstehen, was ich mit Worten beschrieben habe, brauchst Du nicht programmieren zu können und erst recht keine Programmiersprache zu können. Wenn man sich etwas konzentriert kann man das auch so verstehen ganz ohne Vorkenntnisse.

Dann legst Du eine Variable m_numberofSize an, die Du gleich (ohne Initialisierung!) als Obergrenze für die for-Schleife benutzt. Erstens sollen nur Membervariablen ein "m_..." vorne dran haben, aber das ist ja eine lokale Variable in der Methode. Kennst Du den Unterschied zwischen Membervariablen einer Klasse und lokalen Methoden-Variablen?
Aber ich frage mich: Hast Du Dir überlegt, was in dieser Variable überhaupt drin stehen soll? Du musst doch irgendeine Idee gehabt haben? Oder hast Du das einfach irgendwie irgendwoher kopiert und wunderst Dich jetzt, dass ich sage, das ist alles Quatsch?

Mach doch einfach mal folgendes ganz ohne sortieren: Lege ein neues Array mit m_numberOfEntries + 1 an. Dann mache eine for-Schleife über alle Elemente im m_entries Array und kopiere jedes einzelne Element vom m_entries Array in das neu angelegt Array um.
Danach kopierst Du das übergebene entry an die letzte Stelle des neu angelegten Arrays, die ja noch frei sein muss, weil Du es ja um eins größer angelegt hattest.
Dann delete[]-e das m_entries Array und weise dem m_entries-Zeiger das oben erstellte neue Array zu.
Wenn Du das hinbekommst können wir schauen, wie wir das so erweitern können, dass der neue Eintrag in die richtige Stelle eingefügt wird.

Gruß
Marco
Auf diesen Beitrag antworten »
Victor

Ich versuche jetzt ein wenig deinen Code zu verstehen und mache mich dann an einer neuen Aufgabe ran .

Was machst du hier genau ?
Oder sind hier nicht Schreibfehler drin ?

code:
1:
2:
3:
4:
	newEntries[alreadyInserted ? i + 1 : i] = m_entries[i];

Auf diesen Beitrag antworten »
as_string

Ok.
Wahrscheinlich kennst Du den Operator a?b:c nicht. Das ? und : ist zusammen ein Operator, nur dass er nicht wie + oder / oder so zwei Operanden hat, sondern 3.
Das funktioniert so: der Ausdruck "a ? b : c" nimmt den Wert b an, wenn a wahr ist, aber c, wenn a falsch ist.
Was bedeutet das hier?
In der eckigen Klammer steht quasi ein i + 1, wenn alreadyInserted wahr ist, aber nur i, wenn alreadyInserted noch nicht wahr ist.
Ich will ja aus dem Array m_entries alle Elemente rüber ins newEntries kopieren. Zuerst, wenn ich den neuen Eintrag noch nicht eingefügt habe, muss ich das erste Element von m_entries auf das erste Element von newEntries kopieren, das zweite an die zweite Stelle und so weiter. Wenn ich aber irgendwann den neuen entry in newEntries eingefügt habe, bin ich ja in newEntries schon einen Platz weiter als in m_entries. Also muss ich ab dann an die Stelle i+1 kopieren.

Gruß
Marco
Auf diesen Beitrag antworten »
as_string

alternativ könnte man auch schreiben:
code:
1:
2:
3:
4:
5:
6:
if(alreadeInserted)
    newEntries[i + 1] = m_entries[i];
else
    newEntries[i] = m_entries[i];

aber ich mag es kurz und knackig...

Gruß
Marco
Auf diesen Beitrag antworten »
Victor

Woher wusstest du das das Array bereits sortiert ist ?
In der Aufgabenstellung steht das ja nicht
Auf diesen Beitrag antworten »
Victor

Ich habe jetzt versucht das zu machen was du gesagt hast :

code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:

* CCalendar.cpp
 *
 *  Created on: 21.08.2017
 *      Author: vaio
 */

#include "CCalendar.h"




CCalendar::CCalendar() {


}

CCalendar::~CCalendar() {
	if( m_entries >=0 ){
	delete m_entries;
	}
}

Calendar& operator+=(const CCalendarEntry& entry){

	CCalendarEntry * oldEntries = m_entries; 
	CCalendarEntry * newEntries = new CCalendarEntry [m_numberofEntries + 1];
	
	for(i=1; i<m_numberofSize; i++){
		
		oldEntries[i] = newEntries[i];kopiere jedes einzelne Element vom m_entries Array in das neu angelegt Array um.
		newEntries [i] = newEntries[i+1]; Danach kopierst Du das übergebene entry an die letzte Stelle des neu angelegten Arrays, die ja noch frei sein muss, weil Du es ja um eins größer angelegt hattest.
		}
	m_entries = newEntries;  // m_entries auf das neue Array zeigen lassen
	    delete [] oldEntries;  // das alte Array zerlegen

	    } 





Mir ist es egal ob du denkst ,dass ich nichts peile .
Ich will es irgendwie selbst schaffen großes Grinsen e
Auf diesen Beitrag antworten »
as_string

Das sieht ja schon deutlich vernünftiger aus, aber...

Zeile 31: bei einer Zuweisung mit dem Gleichheitszeichen, wird von rechts nach links kopiert, dem linken wird das rechte zugwiesen, nicht umgekehrt. Wenn Du also in das neue Array kopieren willst, muss das logischerweise links stehen.

Zeile 32 willst Du ja nur einmal machen, nachdem Du alle anderen Elemente schon kopiert hast. Das darf dann nicht in der for-Schleife stehen, sonst wird das doch auch bei jedem Schleifendurchlauf ausgeführt und nicht nur einmal.
Dann verstehe ich nicht, warum Du in der Anweisung etwas komplett anderes kopierst, als Du im Kommentar schreibst. Du willst das neu übergebene entry irgendwo hin kopieren. Also haben wir gelernt dass es rechts stehen muss weil von rechts nach links kopiert wird. Aber in der ganzen Zeile steht nichts von entry.
Dann darf links nicht i in der eckigen Klammer stehen. Da die Anweisung ja so wie so außerhalb der for-Schleife stehen muss, darf da gar kein i mehr vorkommen. Stattdessen musst Du Dir überlegen, was der höchste Index ist, der noch in dem neu angelegten Array drin ist.
Du hast das Array oben mit der Größe m_numberOfEntries + 1 angelegt (vorsicht! Du hast schon wieder ei. Kleines o geschrieben, so kann er die Variable nicht finden!). Die Indizes eines Arrays gehen in C++ immer von 0 bis Arraygröße minus eins. Der höchste Index wäre hier also (m_numberOfEntries + 1) - 1 = m_numberOfEntries.
Deine Zuweisung muss also wie aussehen?

Am Ende musst Du noch m_numberOfEntries um einschließlich zählen, das fehlt auch noch.

Gruß
Marco
Auf diesen Beitrag antworten »
Victor

code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:

* CCalendar.cpp
 *
 *  Created on: 21.08.2017
 *      Author: vaio
 */

#include "CCalendar.h"




CCalendar::CCalendar() {


}

CCalendar::~CCalendar() {
        if( m_entries >=0 ){
        delete m_entries;
        }
}

Calendar& operator+=(const CCalendarEntry& entry){

        CCalendarEntry * oldEntries = m_entries; 
        CCalendarEntry * newEntries = new CCalendarEntry [
  (m_numberOfEntries + 1) - 1   ];     
        for(i=0; i<m_numberofSize; i++){
                
                oldEntries[i] = entry;kopiere jedes einzelne Element vom m_entries Array in das neu angelegt Array um.
               
                }
         entry = newEntries[i+1]; D
        m_entries = newEntries;  // m_entries auf das neue Array zeigen lassen
            delete [] oldEntries;  // das alte Array zerlegen

            } 







Wo muss ich m_numberOfEntries++ hinschreiben ?
Ist mir nicht klar ?

Warum heisst das neu angelegte Array entry und nicht newEntry ?

CCalendarEntry * newEntries = new CCalendarEntry [
(m_numberOfEntries + 1) - 1 ];
Auf diesen Beitrag antworten »
Victor

Ich habe auch die if Bedingung ein wenig eingebaut mithilfe des obigen codes.

Kann man nicht statt einer bool variable irgendwas anderes machen?

code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
* CCalendar.cpp
 *
 *  Created on: 21.08.2017
 *      Author: vaio
 */

#include "CCalendar.h"




CCalendar::CCalendar() {


}

CCalendar::~CCalendar() {
        if( m_entries >=0 ){
        delete m_entries;
        }
}

Calendar& operator+=(const CCalendarEntry& entry){

        CCalendarEntry * oldEntries = m_entries; 
        CCalendarEntry * newEntries = new CCalendarEntry [
  (m_numberOfEntries + 1) - 1   ];     
        for(i=0; i<m_numberofSize; i++){
                f( (entry.getDate() < m_entries[i].getDate())) {
                        newEntries[i] = entry;
...........................................................................................
                        
                }

                oldEntries[i] = entry;kopiere jedes einzelne Element vom m_entries Array in das neu angelegt Array um.
               
                }
         entry = newEntries[i+1]; D
        m_entries = newEntries;  // m_entries auf das neue Array zeigen lassen
            delete [] oldEntries;  // das alte Array zerlegen

            } 

Auf diesen Beitrag antworten »
Victor

Hatte vergessen das kopieren zu korriegieren:

code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:

* CCalendar.cpp
 *
 *  Created on: 21.08.2017
 *      Author: vaio
 */

#include "CCalendar.h"




CCalendar::CCalendar() {


}

CCalendar::~CCalendar() {
        if( m_entries >=0 ){
        delete m_entries;
        }
}

Calendar& operator+=(const CCalendarEntry& entry){

        CCalendarEntry * oldEntries = m_entries; 
        CCalendarEntry * newEntries = new CCalendarEntry [
  (m_numberOfEntries + 1) - 1   ];     
        for(i=0; i<m_numberofSize; i++){
                f( (entry.getDate() < m_entries[i].getDate())) {
                         entry = newEntries[i] ;
                        
                }

                oldEntries[i] = entry;kopiere jedes einzelne Element vom m_entries Array in das neu angelegt Array um.
               
                }
          newEntries[i+1]= entry ; D
        m_entries = newEntries;  // m_entries auf das neue Array zeigen lassen
            delete [] oldEntries;  // das alte Array zerlegen

            } 


Auf diesen Beitrag antworten »
as_string

Das mit dem letzten Index und der Arraygröße hast Du gerade falschrum verstanden:
Beim Anlegen eines neuen Arrays musst Du die Größe angeben. Die ist hier m_numberOfEntries + 1, weil das neue eins größer sein soll, das hat also schon gestimmt gehabt.
Aber beim kopieren des neuen Eintrags an letzter Stelle des neuen Arrays musst Du den letzten Index nehmen. Der ist aber immer genau eins kleiner als die Größe des Arrays (ist doch logisch: Wenn Du 3 "Dinger" in der Hand hast und diese von 0 an durchnummerierst, also dem ersten gibst Du den index 0, dann 1 dann 2, dann ist der höchste Index 2 obwohl Du 3 in der Hand hast).
Wenn Du aber von m_numberOfEntries + 1 wieder 1 abziehst, dann kommt m_numberOfEntries raus (Du brauchst nicht +1 und dann wieder -1 schreiben, das hatte ich nur so gemacht, um zu verdeutlichen, dass ich eigentlich von der Arraygröße eine Eins abgezogen habe, was aber in diesem Fall eben gerade zum alten m_numberOfEntries-Wert führt).

Schlagen könnte ich Dich dafür, dass Du schon wieder m_numberofSize benutzt! Die Variable gibt es hier doch überhaupt gar nicht und hat es auch noch nie gegeben! Sei doch mal etwas konzentriert, ist ja wirklich schlimm... Das hat auch nichts damit zu tun, ob Du Dir schwer tust mit Programmieren oder nicht, sondern ist schlicht Schlamperei!

Schlimm finde ich auch, dass Du immer noch die Zuweisungen falsch herum machst!
Angenommen ich habe zwei int-Variablen a und b, a habe den Wert 1 und b den Wert 2. Welchen Wert haben beide dann nach der Zeile:
a = b;

Die Zeile 34 ist wieder völliger Blödsinn. Du schreibst im Kommentar richtig, was Du machen willst. Da schreibst Du was von neuem Array, wo bitte kommt aber das neue Array in Deiner Anweisung überhaupt auch nur vor??? Das kann doch nicht sein, wenn ich schreibe, ich will was von m_entries ins neue Array kopieren das neue Array überhaupt gar nicht vorkommt. Davon abgesehen ist die Zuweisungsrichtung auch wieder falsch, vermute ich.

Zeile 37 verwendet i. Das ist aber nach dem Schleifendurchlauf auf dem Wert von m_numberOfEntries und der letzte Index ist dann nicht i+1 sonder m_numberOfEntries. Allerdings ist da auch wieder ein neues Problem: Du verwendest die ganze Zeit die Variable i, die ist aber nirgends deklariert. Welchen Typ hat den die Variable überhaupt, das steht ja nirgends.
Dann würde ich außerhalb der for-Schleife i. A. die Indexvariable der for-Schleife i gar nicht mehr verwenden. Eigentlich willst Du ja auf das letzte Element von newEntries zugriefen, das ist aber einfach newEntries[m_numberOfEntries] wie ich schon mehrfach geschrieben habe.

Was ich aber nicht verstehe: Du hast in der Schleife jetzt ein if() mit einem Datumsvergleich eingebaut (beim if fehlt übrigens das i) und schiebst dann auch an der richtigen Stelle den neuen Termin ein. Das machst Du übrigens ab diesem Zeitpunkt dann immer. Du musst Dir irgendwie merken, ob Du entry schon ins neue Array kopiert hast oder nicht! Du darfst entry nur einmal einfügen. Insbesondere darfst Du entry auch nur dann an die letzte Stelle kopieren, wenn Du vorher das noch nicht eingefügt hast. Ich verstehe auch gar nicht, warum wir jetzt mit der einfachen Sache angefangen hatten, dass wir die Sortierung für den Moment mal ignorieren und einfach immer hinten einfügen, aber Du jetzt wieder diese if-Anweisung überhaupt drin hast.
Danach musst Du Dir noch überlegen, was eigentlich mit dem Zielindex des neuen Arrays ist, wenn Du entry schon eingefügt hast. Ich habe das jetzt schon einige Male versucht zu erklären, bringt wohl auch nichts, wenn ich es nochmal versuche...

Gruß
Marco
Auf diesen Beitrag antworten »
Victor

Ok ich gebe jetzt einfach auf und fange mit einer neuen Aufgabe an .

Ich glaube das ist noch einfach zu schwer für mich im Moment.

Vielleicht wird es mit der Zeit besser .

Melde mich glaube ich heute noch mit ner neuen Aufgabe großes Grinsen
Auf diesen Beitrag antworten »
as_string

Ich denke, Du solltest Dir wirklich zuerst die Grundlagen aneignen, glaube mir, macht viel mehr Sinn!

Gruß
Marco
 
Neue Frage »
Antworten »


Verwandte Themen

Die Beliebtesten »
Die Größten »
Die Neuesten »