Zeichenkette umdrehen
-
Arcoth schrieb:
void reverse( char* first, char* last ) { while( first < last ) std::iterator_swap( first++, --last ); // Edit: Muss natürlich --last heißen, schließlich zeigt last auf die Adresse hinter dem letzten Element }
Ist es denn wirklich nötig, in einem Ausdruck drei völlig unterschiedliche Sachen zu machen?
Wozu std::iterswap?
Hast nen total anderen Aufruf als den geforderten.
-
Ist es denn wirklich nötig, in einem Ausdruck drei völlig unterschiedliche Sachen zu machen?
Jetzt tuh nicht so.
Wozu std::iterswap?
Damit man das ganze
"allgemein"1337-H@ck0r-maessig haelt. Ich habe nicht viel Motivation das ganze vernuenftig zu machen, wenn der Fragesteller wenig Initiative zeigt.(siehe auch Skym0sh0s Post)
Wenn ihr eine verstaendliche Loesung mit Kommentaren haben wollt, die koennt ihr gerne haben:
void reverse( char* first, char* last ) // nach C++-Konvention zeigen die Zeiger jeweils auf den Anfang und auf die Adresse hinter dem Ende des Arrays. { --last; // jetzt zeigt last auf das letzte Element while( first < last ) // waehrend wir uns nicht in der Mitte treffen... { std::swap( *first, *last ); // vertausche zwei Elemente ++first; // ... und aendere die Iteratoren so, dass sie auf das naechste zu vertauschende Paar zeigen. --last; } } // Wenn also die Paare Buchstaben erhalten, kann man die einer Menge mit bspw. sieben Elementen folgendermassen beschriften // A B C D C B A // Es werden also beide mit A gekennzeichneten Elemente vertauscht, dann beide B-Elemente usw.
-
Arcoth, deine Implementierung braucht Random-Access-Iteratoren, wegen
operator<
. Zum Umkehren reichen aber bidirektionale.
-
Zum Umkehren reichen aber bidirektionale.
Klar, dann wird es (die Abbruchbedingung) aber komplizierter. Weil man prüfen muss, ob die Iteratoren einander gleichen, oder ob sie nur einen Schritt von einander entfernt sind. GCC implementiert das übrigens so*:
while (true) if (first == last || first == --last) return; else { std::iter_swap(first, last); ++first; }
Bei sowas hätte mich Volkard massakriert.
Wie würde man es nun schön schreiben? Ich hätte, wenn es wirklich gut leserlich sein sollte, dazu tendiert:for(;;) { if( first == last || std::next(first) == last ) break; std::iter_swap(first, last); ++first; --last; }
* Warum schreiben die so ein komisches Zeug? Scheuen die sich davor, den Code in der Schleife in Klammern zu setzen?
-
Arcoth schrieb:
Bei sowas hätte mich Volkard massakriert.
Wie würde man es nun schön schreiben? Ich hätte, wenn es wirklich gut leserlich sein sollte, dazu tendiertLass uns die Aufgabe verschärfen:
Welchen Code kannste noch lesen, wenn Du rotzbesoffen bist, frisch verliebt bist, einen grippalen Infekt am schlimmsten Tag (2 Tage, nachdem Dir so elend kalt war) brütest, und Dir gerade der Amboß auf den großen Zeh gefallen ist? Natürlich soll er performant bleiben, ist das || mit std::next im Schleifenkörper nötig?
-
[quote="Arcoth"]GCC implementiert das übrigens so*:[/code]
Arcoth schrieb:
* Warum schreiben die so ein komisches Zeug? Scheuen die sich davor, den Code in der Schleife in Klammern zu setzen?
Was sagst Du, wenn Dein Arbeitgeber mal zu Besuch ist und das Essen ihm nicht so schmeckt?
Den Klassiker seit >3000 Jahren: "Es ist ja soooo schwer, gutes Personal zu finden (traurig guck)".Arcoth schrieb:
Bei sowas hätte mich Volkard massakriert.
Du wärst sofort in die Gruppe "Betreutes Programmieren" gekommen.
-
Die Implementierung aus der libcxx:
template <class _BidirectionalIterator> inline _LIBCPP_INLINE_VISIBILITY void __reverse(_BidirectionalIterator __first, _BidirectionalIterator __last, bidirectional_iterator_tag) { while (__first != __last) { if (__first == --__last) break; swap(*__first, *__last); ++__first; } } template <class _RandomAccessIterator> inline _LIBCPP_INLINE_VISIBILITY void __reverse(_RandomAccessIterator __first, _RandomAccessIterator __last, random_access_iterator_tag) { if (__first != __last) for (; __first < --__last; ++__first) swap(*__first, *__last); } template <class _BidirectionalIterator> inline _LIBCPP_INLINE_VISIBILITY void reverse(_BidirectionalIterator __first, _BidirectionalIterator __last) { _VSTD::__reverse(__first, __last, typename iterator_traits<_BidirectionalIterator>::iterator_category()); }
-
Avorox schrieb:
Hallo,
ich habe die folgende Aufgabe in der Schule von meinem Lehrer bekommen:
Beispiel:
char Kette [6] = "Hallo";
Umdrehen (Kette);
cout << Kette; //gibt "ollaH" auf dem Bildschirm ausNun habe ich leider keine Ideen zur Lösung dieser Aufgabe, kann mir da jemand helfen?
Mit einer for() Schleife das die Array Zeichenkette rückwärts ausgibt.
Wenn man verinnertlicht hat durch viel Praxis und probieren, wie eine Schleife funktionert und Arrays, dann weiss man sofort wie das geht. Ist recht simpel.
-
Aber Jungs, was hab ich gesagt.
Der TE meldet sich nichtmals mehr, ergo ist dieser Thread sinnlos für die eigentliche Fragestellung. Da kann man auch andere Dinge hier diskutieren...
-
Natürlich soll er performant bleiben, ist das || mit std::next im Schleifenkörper nötig?
Ne, das ist tatsächlich völlig überflüssig.
Wie wäre es mit
--last; for(;;) { if( first == last ) break; std::iter_swap(first, last); --last; if( first == last ) break; ++first; }