Zeichenkette umdrehen



  • Glückwunsch Arcoth,
    schon wieder eine Lösung für die didaktische Müllhalde.

    Ich frage mich wann so manche hier endlich mal verstehen, wie man auf dem Programmierniveau des Fragestellers antwortet und nicht einfach nur eine Lösung rauskotzt, die den Kenntnisstand weit übersteigt.



  • qweasdyxc schrieb:

    Glückwunsch Arcoth,
    schon wieder eine Lösung für die didaktische Müllhalde.

    Ich frage mich wann so manche hier endlich mal verstehen, wie man auf dem Programmierniveau des Fragestellers antwortet und nicht einfach nur eine Lösung rauskotzt, die den Kenntnisstand weit übersteigt.

    Und du bist einer, der nicht verstanden aht, dass hier keine Hausaufgaben geschenkt werden.

    Der Threadersteller ist offensichtlich Anfänger, aber hat auch mehr als offensichtlich keinerlei Motivation selbst etwas beizusteuern. Er wird heute nachmittag nochmal in den Thread schauen, die erste oder zweitbeste Lösung mal Copy&Pasten, vllt vorher nochmal danke sagen und dann nicht mehr wieder kommen.

    Und Arcoth hat sich ziemlich nett ausgedrückt und sich verhältnismäßig viel Mühe gegeben. Eine ganze Reihe anderer Leute haben sich nicht die Mühe gemacht auch nur irgendwas zu schreiben.



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


  • Mod

    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.


  • Mod

    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 tendiert

    Lass 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 aus

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


  • Mod

    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;
    }
    

Anmelden zum Antworten