Turmbau zu Babel
-
http://www.lmgtfy.com/?q=c%2B%2B+vector
Gleich der erste dicke Treffer
-
Hilbert schrieb:
Also erstmal vielen vielen Dank für die Hilfe.
Leider gibt es Sachen, die ich noch nicht so ganz verstehe, gerade bei Klassen.
Vielleicht könntest du sie mir erklären:class Scheibe { private: uint dicke; public: Scheibe(uint dicke): dicke(dicke){} uint get_dicke() const {return dicke;} };
Was genau sagt mir jetzt die Zeile Scheibe(uint dicke): dicke(dicke){} ?
Das ist ein sogenannter Konstruktor mit Initialisierungsliste. Die Stichworte sollten zum Googeln reichen.
Typedef kenne ich auch noch nicht, aber ich glaube es spart einfach an Platz, oder? Man sagt typedef unsigned int nenne ich jetzt nur noch uint. Richtig?
Ja, hier habe ich das aus Schreibfaulheit gemacht. Der eigentliche Zweck kommt unten.
Des Weiteren verstehe ich etwas in folgendem Abschnitt nicht:
typedef std::vector<Scheibe> Saeule; void verschiebe(Saeule &von, Saeule &nach) { nach.push_back(von.back()); von.pop_back(); }
Was ist nach.push_back und von.pop_back?
Und die Typedef Zeile bleibt mir schleierhaft.Dies ist der eigentliche Zweck von typedef: Namen zentral definieren. Ich kann im ganzen Programm
Saelue
schreiben, wenn ich eigentlichstd::vector<Scheibe>
meine. Dadurch kann ich das wofür Saeule steht mit minimalem Aufwand auswechseln, wenn der Bedarf besteht. Genauso wie ich ja bei der Herleitung des Programms von stack auf vector gewechselt bin.Oder ist das alles schon vorimplementiert als Vektor mit seinen Befehlen in der Bibliothek?
Genau. vector ist eine ganz wichtige Klasse der Standardbibliothek (genauer: ein Klassentemplate, aber das sagt dir vermutlich noch nichts). Es ist eine Ansammlung von Werten die man flexibel erweitern kann und über ihren Namen und die Nummer ansprechen kann:
std::vector<int> foo(6);
hat zum Beispiel 6 Elemente vom Typ int, die überfoo[0]
bisfoo[5]
ansprechbar sind. Die Methodepush_back
fügt hinten ein Element an,pop_back
löscht das hinterste Element.Zu guter letzt verstehe ich diese Zeile nicht:
for (Saule::const_iterator it = A.begin(); it != A.end(); ++it)
Dies ist ein anderes wichtiges Konzept der Standardbibliothek: Iteratoren
Da Saeule bei mir ein vector ist, hätte ich auch folgendes machen können:for (int i=0; i<A.size(); ++i) // stelle A[i] dar
Und das wäre auch vollkommen korrekt für vector, weil vector auf jedes beliebige Element zugreifen kann, wenn man ihm die Nummer des Elements vorgibt. Aber wir wollen flexibel bleiben und eventuell vector durch etwas anderes ersetzen, wenn Bedarf besteht. Etwas was vielleicht nicht Zugriffe wie A[i] kennt, zum Beispiel eine
std::list
(so ähnlich wie vector, aber intern anders organisiert, wodurch gewisse Aktionen schneller oder langsamer sind als bei vector, beispielsweise ist Zugriff auf das i-te Element so langsam, dass es gar nicht angeboten wird, dafür ist Einfügen in der Mitte viel schneller als bei vector). Wir brauchen bei der gezeigten Schleife auch gar nicht immer auf das i-te Element zuzugreifen, sondern wir wollen immer bei jedem Schleifendurchgang auf das nächste Element zugreifen, bis wir am Ende angelangt sind. Iteratoren sind eine allgemeine Schnittstelle um Container schrittweise durchzugehen, eine Aufgabe die sehr häufig vorkommt. Die Iteratoren werden von allen Containern der Standardbibliothek angeboten (außer Spezialcontainern wie stack, die bewusst darauf verzichten). Und wenn man selbst Containerklassen schreibt, sollte man auch Iteratoren dafür anbieten. Das heißt ich könnte den vector gegen irgendeinen Container austauschen, ohne an dem Programm irgendwas zu ändern, weil ich auf die Spezialeigenschaft des vectors (Zugriff a laA[i]
) verzichtet habe und stattdessen das abstraktere Konzept der Iteratoren benutzt habe.
-
Habe mal probiert dein Klassenprogramm in mein Funktionen&Array-Programm zu übertragen.
Aber ich schaffe es nicht..Ich habe die Arrays gegeben:
int Stab_1[AnzahlderScheiben]; int Stab_2[AnzahlderScheiben]; int Stab_3[AnzahlderScheiben];
So sieht meine Babelfunktionen aus:
void babel(int Scheiben, int von, int nach, int Hilf) { if (Scheiben == 0) return; babel(Scheiben-1,von,Hilf,nach); bewege (von,nach); zeichne(); babel(Scheiben-1,Hilf,nach,von); }
Das Problem habe ich mit
void bewege(int von, int nach) { }
Hier muss ich mit den Arrays arbeiten, leider geht das immer in die Hose.
Könnt ihr mir hier helfen?Die Funktion zeichne () habe ich.
Vielen,vielen Dank.
-
Wie stellt sich bei deinen Arrays denn dar, welche Scheiben auf einem Stab sind?
Gehe ich Recht in der Annahme, dass du dies selber nicht so genau weißt? Hier liegt dann nämlich die Wurzel deines Problems.
-
Stab_1: {5, 4, 0, 0, 0}
Stab_2: {3, 2, 1, 0, 0}
Stab_3: {0, 0, 0, 0, 0}
Stab_array: {{5, 4, 0, 0, 0},
{3, 2, 1, 0, 0},
{0, 0, 0, 0, 0}}
sieht so aus:
| | |
| | |
| <|> |
<<<<|>>>> <<|>> |
<<<<<|>>>>> <<<|>>> |
-------------------------------------
-
Dann wirst du dir entweder merken müssen, wo die Spitze ist (hier bietet sich wieder eine Klasse an oder eben gleich std::vector, welcher das sowieso schon macht) oder du musst immer die Spitze suchen. Und dann tauscht du.
-
Wie suche ich denn die Spitze?
Dann muss ich doch eine neue Funktion getSpitze() schreiben oder?
also void getspitze()
und da die kleinste zahl aus dem stab suchen.
Aber wie?
-
Das oberste Element ist das letzte, welches keine 0 ist.
-
Also:
void getspitze()
Wie suche ich denn Zahlen in einem array?
Da muss doch sowas sein wie
if x == 1
....
if x == 2
..usw.
Ich kann das mit Arrays einfach überhaupt nicht.
-
Hilbert schrieb:
Ich kann das mit Arrays einfach überhaupt nicht.
Das sehe ich auch. Wieso machst du es dann damit? Arrays sind eine eher schlechte Lösung für die Problemstellung.
-
Das ist eine Aufgabe die wir machen müssen.
Habe leider nicht mehr viel Zeit und zerbreche mir schon eine Woche den Kopf darüber.Sowas hab ich bis jetzt:
if (Stab_array[from][5] > 0)
Stab_array[from][5] = 0
else
{
if (Stab_array[from][4] > 0)
Stab_array[from][4] = 0
else
{
if (Stab_array[from][3] > 0)
Stab_array[from][3] = 0
else
{
if (Stab_array[from][2] > 0)
Stab_array[from][2] = 0
else
{
if (Stab_array[from][1] > 0)
Stab_array[from][1] = 0
else
{
if (Stab_array[from][0] > 0)
Stab_array[from][0] = 0Aber das ist mal wieder total falsch.. Eher Augenkrebsfördernd für euch.
}
-
Wenn du mehrere Wochen Zeit hattest, warum hast du die Zeit nicht mal genutzt um die Grundlagenkapitel irgendeines Lehrwerks anzusehen? Das wäre eine Sache von 30 Minuten gewesen. Jetzt ist es ein bisschen spät.
-
SeppJ schrieb:
Turmbau zu Babel macht die Sache aber viel einfacher:
void baue_turm(unsigned &anzahl_stockwerke) { baue_turm(++anzahl_stockwerke); } int main() { unsigned anzahl_stockwerke=0; baue_turm(anzahl_stockwerke); }
[...]
Naja, der Geschichte nach müsste man den Overflow noch irgendwie abfangen. Da ja besagter Turm heute nicht mehr steht, könnte man auch eine
turm
-Klasse nehmen und am Ende einen destructor aufrufen...Und dann ein
cout << "Und zur Strafe schuf der Herr BASIC, FORTRAN, PL1, Postscript, C++, Java, Perl, Assembler, Lisp, Python, Occam ..... ";