(einfache) Iterator-Aufgabe hässlich gelöst?
-
Hi!
Hab mir ein Buch besorgt und bin dabei es seit einer Woche durchzuarbeiten.
Im Buch werden zu jedem Kapitel Aufgaben gestellt leider aber keine Lösungen.
Die Aufgabe lautet als erstes eine Reihe an eingegebenen integer Zahlen in einen vector zu schreiben. Dabei sollen dann jeweils zwei benachbarte Zahlenpaare zusammen addiert und ausgegeben werde. Falls eine ungerade Zahl an Eingaben getätigt wurde soll die letzte einfach ausgegeben werden.
Dasselbe soll dann in der zweiten Aufgabe nochmals durchgeführt werden, nur dass die erste und die letzte Zahl addiert werden sollen. Hier soll hauptsächlich der []- index operator verwendet werden.Bsp: Eingabe von 3 Zahlen: 4, 8, 12
Ausgabe
(1)
4 + 8 = 12
12(2)
4 + 12 = 16
8Im nächsten Kapitel aber wo eine kleine Einführung zu Iteratoren stattfindet ist eine weitere Aufgabe bei der ich die vector-Aufgabe neu schreiben soll und statt den index Iteratoren einsetzen soll.
Ich habs hingekriegt nur finde ich dass ich es, besonders bei 2, zu umständlich gemacht hab. Geht es auch in 1. Schleife und eventuell nur mit 1. Zählvariable?void paarrechnen1() { vector<int> zahlen; int eingabe; while (cin >> eingabe) zahlen.push_back(eingabe); for (vector<int>::const_iterator zähler = zahlen.begin(); zähler < zahlen.end(); zähler+=2 ) { if (zähler == zahlen.end() - 1) {cout << *zähler; break;} else cout << *zähler << " + "; //wenn ich alles in 1 zeile schreibe, werden falsche zahlen ausgegeben, trenne ich sie in mehrere auf klappts. warum? cout << * (++zähler) << " = "; cout << (*(--zähler) + *(++zähler)) << endl; --zähler; } }void paarrechnen2 () { vector<int> zahlen; int eingabe; while (cin >> eingabe) zahlen.push_back(eingabe); if (zahlen.size() % 2 == 0) //geht das herausfinden ob eine ungerade oder gerade eingabe getätigt wurde auch in 1 schleife? for (vector<int>::const_iterator count = zahlen.begin(), count_max = zahlen.begin() + zahlen.size(); count != zahlen.begin() + zahlen.size() / 2; count++ ) { count_max--; cout << *count << " + " << *count_max << " = " << *count + *count_max << endl; } else for (vector<int>::const_iterator count = zahlen.begin(), count_max = zahlen.begin() + zahlen.size(); count != zahlen.end(); count ++) { count_max--; if (count == count_max) cout << *count << endl; else cout << *count << " + " << *count_max << " = " << *count + *count_max << endl; } }
-
Zu dem ersten Programm:
cout << *zähler << "+" << *(zähler + 1) << "=" << *zahler + *(zähler + 1) << endl;Gewöhne dir bitte die Umlaute ab, die meisten Compiler haben damit Probleme!
Das else kannst du übrigens weglassen.Zu dem zweiten Programm:
auto start = zahlen.cbegin(); // const_iterator auto end = zahlen.crbegin(); // const_reverse_iterator for (; start != zahlen.begin() + zahlen.size() / 2; ++start, ++end) cout << *start << "+" << *end << "=" << *start + *end << endl; if (zahlen.size() % 2 != 0) cout << *start << endl;
-
Eingabe, Ausgabe und Berechnung trennen!
Sonst so: Wie veraendert sich die Ausgabe bei Aufgabe 1., wenn du bei einer ungeraden Anzahl einfach eine 0 zusaetzlich anhaengst? Jetzt hast du immer nur eine gerade Anzahl von Elementen im Vektor und brauchst weniger ifs. Sofern nur deren Summe ausgegeben werden soll. Gut, der Trick funktioniert bei Aufgabe 2 nichtmehr.
Do not do this:
cout << (*(--zähler) + *(++zähler)) << endl;Zu Aufgabe 2: Wenn der Indexoperator verwendet werden soll, warum verwendest du ihn nicht?
-
Wow, dass die 2.Schleife so einfach gehen kann gut zu wissen danke.
Ich glaube bei Aufgabe 1 meinst ducout << *zähler << "+" << *(zähler + 1) << "=" << *zähler + *(zähler + 1);Ich versteh ja, dass bei mir die zähler erhöhe und so eben nicht, aber wieso funktionieren meine 3 cout Zeilen (ich weiß so soll man das nicht machen), wenn ich sie aber nur in 1 cout zeile schreibe, dann erst wird die Ausgabe falsch? Ist es wegen der Position des ++? Ich will es nur verstehen.
@knivil
Uhh das mit dem 0 dranhängen ist auch eine gute Idee, muss ich mir merken!
Ich spiel gerne mit den Aufgaben herum um zu wissen, was ich alles mit den in den Kapitel besprochenen Themen machen kann und weil ich nicht immer alles wegkommentieren will klatsch ich mehr oder weniger alles zusammen, es ist nur zu Lernzwecken :D!Nein das mit den Indexoperatoren habe ich in der Aufgabe davor schon gemacht. In dieser sollte ich dasselbe machen nur sie einfach durch Iteratoren ersetzen einfach um ein bisschen vertraut damit zu werden und fand meine Lösung irgendwie blöd oder überhaupt Iteratoren, wenn es mit dem index so einfach geht. Anscheinend kommt in den späteren Kapiteln noch was lol.
-
Ja, ich meinte natürlich das, was du geschrieben hast.
Das mit dem ++/-- weiß ich auch nicht so genau.
Und wenn du eh mit Iteratoren herumspielst, versuche doch mal, ein Iteratorenpaar an die Funktion zu übergeben.
Das erste gibt den Anfang der Seqeunz an, mit der das gemacht werden soll, der zweite das Ende.
Dann trennst du auch die Eingabe vom eigentlichen Algorithmus und bist flexibler.
-
Dacen schrieb:
[...] wieso funktionieren meine 3 cout Zeilen (ich weiß so soll man das nicht machen), wenn ich sie aber nur in 1 cout zeile schreibe, dann erst wird die Ausgabe falsch?
Ist es wegen der Position des ++? Ich will es nur verstehen.Dacen schrieb:
cout << *zähler << " + "; // wenn ich alles in 1 zeile schreibe, werden falsche zahlen ausgegeben, // trenne ich sie in mehrere auf klappts. warum? cout << * (++zähler) << " = "; cout << (*(--zähler) + *(++zähler)) << endl;Also alles in einer Zeile:
cout << *zaehler << " + " << *(++zaehler) << " = " << (*(--zaehler) + *(++zaehler)) << endl;Das Problem ist, dass dieser Ausdruck mehrere Nebenenffekte auf
zaehlerhat (mehrere Prefix-In-, bzw. Prefix-Dekrementierungen).
Grundsätzlich ist die Reihenfolge der Auswertung der verschiedenen Operanden eines Ausdrucks nicht definiert ("unsequenced", s. C++11 1.9/15)
Und mehrere Nebeneffekte auf denselben Skalar in nicht definierter Reihenfolge resultieren in "undefined Behaviour" (ebd.)Dacen schrieb:
Hab mir ein Buch besorgt und bin dabei es seit einer Woche durchzuarbeiten.
Im Buch werden zu jedem Kapitel Aufgaben gestellt leider aber keine Lösungen.Welches Buch ist das?
Dein Stil nach einer Woche C++ lässt mich vermuten, dass an dieser Stelle ruhig ein wenig Werbung für das gute Stück gemacht werden könnte...Als Ergänzung zu Deinem Buch kannst Du Dir hier noch den aktuellen C++ Standard runterladen, als unverzichtbare Referenz.
-
@Nathan Hmm, werd ich mal ausprobieren. Wie gesagt ich wollte halt einfach nur den Hauptteil bzw. die Schleife hinkriegen und hab jetzt Ausgabe usw. eher nebensätzlich gesehen.
Das Buch, das ich gerade lese ist der C++ Primer, vierte Auflage(in Englisch). Ich hab die Empfehlung für dieses Buch eigentlich aus diesem Forum her, also eigentlich muss ich Euch danken :). Mir gefällt es dass so vieles erklärt wird, was z.B. bei Tuts nur kurz angeschnitten wird oder mir gesagt wird ich solls einfach "kopieren", ist zwar toll dass es dann klappt aber ich wills auch verstehen. Bin grade mal auf Seite 97, freue mich schon auf die restlichen 800 :D.
Und danke das mit dem undefined behaviour verstehe ich, diese 3 Zeilen sind aus dem verzweifelten Versuch entstanden durch rumspielen am Code die Lösung zu kriegen, haha. Als ich die mir angeschaut hatte dachte ich mir schon, dass es einfach nur grausam ausschaut. Zur Referenz gleich mal ein bookmark gemacht, wird als Ergänzung und Vertiefung bestimmt hilfreich.
-
Nach dieser Methode arbeiten auch die Algorithmen der Standardbibliothek. (Iterator start, Iterator end, ... Iterator ist ein Template)
Auch ein Lesezeichen wert ist auf jeden Fall, die Referenz der Standardbibliothek.