Schleife nimmt meine unsigned-variable nicht !?



  • Hallo an alle hier. Ist wahrscheinlich für euch relativ einfach zu beantworten, allerdings weiss ich nicht wirklich woran es liegen könnte. Hatte irgendwann mal in einem Buch gelesen dass bei einem Vergleich in einer for-Schleife die im Vergleich beteiligten "Teilnehmer" implizit auf unsigned gecastet werden. Deswegen habe ich auch das UNSIGNED in meinem Beispiel drin stehen. Ohne UNSIGNED funktioniert es, aber wieso nicht mit UNSIGNED!?

    void str_umkehr(string &s) {
    	string temp { s };
    	s = "";
    	for (unsigned int lv = temp.length() - 1; lv >= 0; --lv) {
    		s = s + temp.at(lv);
    	}
    }
    

    Es geht im übrigen um die Laufvariable "lv".
    Viele Danke schon mal für eure Zeit und Hilfe.

    lg der UuuugUuug



  • @uuuguuug Was passiert mit einer unsigned Variablen 0 ist und man -1 abzieht?
    Negativ kann sie nicht werden.
    Also gibt es einen Unterlauf auf den Maximalwert.
    Die Variable ist somit größer 0.



  • @uuuguuug BTW du brauchst keinen temp-String, das geht auch In-Place.

    Du musst das erste mit dem letzten Zeichen vertauschen,
    das 2. mit dem vorletzten, ...
    (Wenn du dann aber nochmal das Letzte mit dem Ersten vertauschtst, bist du zu weit gegangen)



  • Du hast natürlich RECHT. Ich bin so dumm. Naja Ich habe jetzt einfach den INDEX geändert und schon hat es funktioniert. Über das ANDERE werde ich nach dem Essen nachdenken.

    Glaube zwar nicht dass es jemanden interessiert aber um das hier abzuschliessen hier meine Änderung. Dann kann das hier auch bei Bedarf geschlossen werden.

    void str_umkehr(string &s) {
    	string temp { s };
    	s = "";
    	for (unsigned int lv = temp.length(); lv > 0; --lv) {
    		s +=  temp[lv-1];
    	}
    }
    

    Gruss der UuugUuug



  • Habe nachgedacht über das Tauschen und ALLES KLARO 😁
    Eins noch, nachdem ich ein wenig genauer nachgedacht habe denke ich dass ich dann aber einen temp_char benötige, oder checke ich da noch was nicht?



  • @uuuguuug

    Die STL (Standard template Library) ist dein Freund, benutze so viel wie möglich daraus.
    Es gibt zb std::reverse, die die Reihenfolge der Elemente in einer range umkehrt.
    Ich gehe davon aus, dass das eine Hausaufgabe ist, in der du den Algorithmus selbst implementieren sollst. Auch da bietet die STL Hilfe in Form von std::swap.



  • @uuuguuug sagte in Schleife nimmt meine unsigned-variable nicht !?:

    ich dann aber einen temp_char benötige

    Ja.

    @DocShoe sagte in Schleife nimmt meine unsigned-variable nicht !?:

    @uuuguuug
    Die STL (Standard template Library) ist dein Freund,

    Davon lernt man aber wenig



  • @DirkB
    Sehe ich anders. Manche Sachen muss man nicht lernen, weil sie trivial sind oder zu komplex für den alltäglichen Gebrauch sind, man muss nur verstehen, wie sie ungefähr funktionieren. std::swap und std::stable_sort sind mMn solche Kandidaten.



  • 3 Dinge fallen mir auf/ein:

    • size() und length() returnen den Typ size_t - daher ist dieser der "natürliche" Typ für deine Schleifenvariable
    • ich würde so eine Umdreh-Funktion standardmäßig nicht inplace machen. Also sowas hier:
      std::string str_umkehr(const std::string &in) {
          return {in.rbegin(), in.rend()};
      }
      
    • wenn inplace, würde ich auch von vorne durchlaufen:
      void str_umkehr_inplace(std::string &s) {
          if (s.size() < 2) return;
          for (size_t i = 0, j = s.size() - 1; i < j; ++i, --j) {
              std::swap(s[i], s[j]); 
          }
      }
      // oder auch mit iteratoren.
      


  • Danke noch mal an Alle hier. Und ja es ist so eine Art Hausaufgabe. Swap() wurde ein Stück weiter oben schon erwähnt, nur hatte ich diese Funktion laut meinem Lehrbuch noch nicht, aber gut zu wissen. Was dieses INPLACE betrifft sagt mir das KONSTRUKT rein garnichts. Das wird nach weiterer Sichtung meines Buches denke ich aber auch noch. Was den TYP "size_t" betrifft meinte ich zu gelesen zu haben, das die Funktion ssize() wohl auch gehen sollte!?

    Gruss



  • @uuuguuug
    Mit "inplace" (manchmal auch in-situ) ist gemeint, dass die Umkehr ohne eigene zusätzliche Zwischenvariablen oder Kopien gelöst werden kann.

    Beispiel mit Kopie:
    Leeren String erzeugen, Zeichen aus dem Ausgangsstring von hinten nach vorne an den String anhängen. Das ist nicht in-place, weil ein zweiter String zum Zusammenbauen gebraucht wird.

    Beispiel inplace:
    Im Eingabestring erst das erste Zeichen mit dem letzten vertauschen, dann das zweite mit dem vorletzten usw, bis man in der Mitte angekommen ist. Man braucht max. ein Zeichen zum Zwischenspeichern beim Tauschen, mit std::swap ist das opak und man sieht´s nichtmal.



  • @DirkB sagte in Schleife nimmt meine unsigned-variable nicht !?:

    @uuuguuug Was passiert mit einer unsigned Variablen 0 ist und man -1 abzieht?

    Ihr wird 1 zugewiesen 🙂



  • @DocShoe sagte in Schleife nimmt meine unsigned-variable nicht !?:

    Mit "inplace" (manchmal auch in-situ) ist gemeint, dass die Umkehr ohne eigene zusätzliche Zwischenvariablen oder Kopien gelöst werden kann.

    Ich meinte eher, dass das Ergebnis in den Parameter geschrieben wird, also per Referenz übergeben wird. Wenn man dagegen eine Kopie zurückgibt, sieht man an der aufrufenden Stelle klarar, was passiert und es wird nicht versteckt etwas geändert. Ob intern in innerhalb der Inplace-Funktion eine Kopie erzeugt wird oder nicht, ist mir von aufrufender Seite erstmal egal.



  • @Tyrdal sagte in Schleife nimmt meine unsigned-variable nicht !?:

    @DirkB sagte in Schleife nimmt meine unsigned-variable nicht !?:

    @uuuguuug Was passiert mit einer unsigned Variablen 0 ist und man -1 abzieht?

    Ihr wird 1 zugewiesen 🙂

    good catch 😉

    Gemeint war von @DirkB natürlich, "wenn man 1 abzieht"... Die Frage ist aber, was bedeutet "-1 abziehen" überhaupt in der unsigned-World?



  • @wob

    Um ehrlich zu sein kommt sowas in Produktivcode doch eh nicht vor. Da steht dann doch sowas wie

    std::reverse( s.begin(), s.end() );
    oder
    std::string r( s.rbegin(), s.rend() );
    


  • @DocShoe sagte in Schleife nimmt meine unsigned-variable nicht !?:

    Um ehrlich zu sein kommt sowas in Produktivcode doch eh nicht vor.

    Doch, natürlich.

    std::cout << reversed(my_string);
    

    list sich viel besser als

    std::cout << std::string(my_string.rbegin(), my_string.rend());
    

    Gerade String-Funktionen sind hier häufig speziell, weil man sie im Kopf anders behandelt als normale Arrays - und teilweise werden String-Funktionen oft benötigt. Und die haben durchaus dann ihre eigenen Namen, eben weil es sich einfacher liest und schreibt. Gut, wie oft muss man einen String umkehren - das ist schon die Frage. Aber immer wenn ich eine Sache öfter brauche, finde ich die std::algorithmen sehr sperrig*. Und es ist dann ja ein Einzeiler, das auf den konkreten Usecase runterzubrechen.

    Spannend wird es zum Beispiel, wenn man utf-8 kodierte Strings hat. Dann funktioniert das nämlich nicht mehr so wie oben, zumindest wenn man die Zeichen korrekt beibehalten will.

    * ich bevorzuge auch eine Funktion "sum" über eine Funktion "std::accumulate", die vielleicht alles machen kann, aber viel mehr machen kann als eine simple Summe.



  • Okay, aber in der Funktion reversed muss der String ja dann auch umgedreht werden, vielleicht benutzt man dann dort die STL?!



  • @Belli sagte in Schleife nimmt meine unsigned-variable nicht !?:

    Okay, aber in der Funktion reversed muss der String ja dann auch umgedreht werden, vielleicht benutzt man dann dort die STL?!

    Ja logisch. So wie ich das da https://www.c-plusplus.net/forum/post/2607886 gezeigt hatte. Ist ja ein 1-Zeiler.
    Das "sum" könnte auch "std::accumulate" nutzen. Nur ist std::accumulate sehr fehleranfällig (schon mehrmals erlebt), daher vermeide ich es gerne (und immer war es die initialiale 0, die 0.0 hätte sein sollen...)


Log in to reply