Palindromtest mit einem Typ string als Rückgabewert



  • Guten Abend,

    ich habe folgende Aufgabe:

    • Programmieren Sie eine Funktion dreh, die einen als string übergebenen Text
      umdreht und den gedrehten Text als Rückgabewert vom Typ string zurückgibt.
    • Schreiben Sie ein Programm, dass mit cin einen Text einliest.
    • Vergleichen Sie den eingelesenen Text mit dem Resultat der Funktion dreh.
    • Geben Sie anschließend das Resultat (Der Text ist ein/ist kein Palindrom am
      Bildschirm aus.

    Dazu mein Lösungsansatz:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <string>
    
    using namespace std;
    
    string dreh(string word)
    {
        string word2;
        for (int i=word.length()-1; i >= 0; i--)
        {
            word2=word[i];
            return word2;
        }
    }
    
    
    int main()
    {
        string word2;
        string word="hooh";
        dreh(word);
        if (word==word2)
            cout << "Der Text ist ein Palindrom." << endl;
        else cout << "Der Text ist kein Palindrom." << endl;
        return 0;
    }
    

    Mein Problem ist, dass der string word2 nicht zurückgegeben wird. Kann mir jemand erklären wie ich das schaffe?



  • Schreib bitte in eine Zeile vor deinen Code ``` und in eine nach deinem Code ``` und rück' ihn ordentlich ein. Danke.

    @Cusher sagte in Palindromtest mit einem Typ string als Rückgabewert:

    word2 = word[i];

    was tut das? Das kompiliert doch nichtmal.



  • Sorry, mit dem folgenden Code würde es gehen oder
    Dann wäre word2 zumindest schon mal mein Wort anders herum geschrieben, dass ich jetzt noch zurück geben muss.

        for (int i=word.length()-1; i >= 0; i--)
        {
            word2=word[i];
            cout << word2;
        }
        cout << endl;
    


  • @Cusher

    Sorry, mit dem folgenden Code würde es gehen oder

    Wäre es nicht einfacher, den Compiler statt das Forum zu fragen?



  • Erstmal, dreh ist wohl der blödeste Name für diese Funktion, den man sich hätte ausdenken können...

    Mein Problem ist, dass der string word2 nicht zurückgegeben wird. Kann mir jemand erklären wie ich das schaffe?

    Du hast noch nicht ganz verstanden, wie Rückgabewerte funktionieren (wenn ich deinen Code so anschaue). Das schaffst du prinzipiell so:

    string return_str(/* ... */) {
        string result;    
        // ...
        return result;
    }
    // ...
    string str = return_str(/* ... */);
    

    Ein return innerhalb der for-Schleife macht hier keinen Sinn. Ebenso wenig ein cout in einer Funktion, welche einen string transformieren soll.

    Am einfachsten ginge das reverse für mich so: return {str.rbegin(), str.rend()};, ist aber vielleicht nicht die schnellste Methode. Sonst gibt es auch std::reverse.

    Um mal ganz konkret bei Deinem Code zu bleiben:

        for (int i=word.length()-1; i >= 0; i--) // OK, aber vorsicht wenn i mal ein unsigned ist.
        {
           // word2=word[i]; // Du weist hier einem string einen char zu, aber eigtl. willst Du ja einen char anhängen
            // das geht so:
            word2 += word[i];
        }
        // das return sollte *nach* der for-Schleife stehen, nachdem alles fertig ist
        return word2
    

    Ich weiß nicht ob das die beste Variante ist, aber es sollte funktionieren (in der Praxis verwendet man lieber vorhandene Funktionalität aus der Standardbibliothek).

    @manni66
    Das traurige ist ja, dass das eben schon kompiliert, ohne Warnungen. Es gibt einen basic_string& operator=( CharT ch ); ---> WTF C++ Standard



  • @Cusher sagte in Palindromtest mit einem Typ string als Rückgabewert:

    word2=word[i];

    Damit weist du word2 jedesmal einen neuen Wert zu.
    Das Zeichen, das an der Stelle i in dem String word steht.



  • Mal ne andere (ähnliche) Frage, warum kompiliert

    std::string a = "test";
    std::string b;
    
    b = a[1];
    

    Während

    std::string a = "test";
    std::string b = a[1];
    

    Eine "conversion from non-scalar type requested" warnung wirft? Ist es weil es keinen Konstruktor für den zweiten Fall gibt?



  • @alfons19 Genau. Schau dir die Liste der string-Konstruktoren an:
    http://www.cplusplus.com/reference/string/string/string/

    und vergleiche sie mit dem Zuweisungsoperator:
    http://www.cplusplus.com/reference/string/string/operator=/

    Dein unterer Code ruft den Konstruktor auf (obwohl von der Syntax her ein = dort steht), aber da gibt es keinen, der einen char nimmt.


  • Gesperrt

    Dieser Beitrag wurde gelöscht!


  • Dieser Beitrag wurde gelöscht!


  • #include <string>
    #include <iostream>
    #include <algorithm>
    
    /*  Programmieren Sie eine Funktion dreh, die einen als string übergebenen Text
     *  umdreht und den gedrehten Text als Rückgabewert vom Typ string zurückgibt.
     */
    std::string dreh(std::string str)
    {
        std::reverse(str.begin(), str.end());
        return str;
    }
    
    int main()
    {
        // Schreiben Sie ein Programm, dass mit cin einen Text einliest.
        std::string text;
        std::cin >> text;
    
        // Vergleichen Sie den eingelesenen Text mit dem Resultat der Funktion dreh.
        bool ist_palindrom{ text == dreh(text) };
    
        // Geben Sie anschließend das Resultat (Der Text ist ein / ist kein Palindrom) am Bildschirm aus.
        std::cout << "Det Text " << (ist_palindrom ? "ist ein" : "ist kein") << " Palindrom.\n\n";
    }
    

    Zu Fuß ohne <algorithm> und std::reverse: kaupt. siehe unten.

    std::string dreh(std::string str)
    {
        auto laenge{ str.length() };
        for (std::size_t i{}; i * 2 < laenge; ++i)
            str[i] = str[laenge - i - 1];
        return str;
    }
    


  • @Swordfish sagte in Palindromtest mit einem Typ string als Rückgabewert:

    Zu Fuß ohne <algorithm> und std::reverse:

    std::string dreh(std::string str)
     {
         auto laenge{ str.length() };
         for (std::size_t i{}; i * 2 < laenge; ++i)
             str[i] = str[laenge - i - 1];
         return str;
     }
    

    Das kopiert dir die hintere Hälfte des Strings umgedreht nach vorne.
    Aus "ab" wird dann "bb".

    Will man das?



  • Hallo @Cusher,
    mein Lehrer in der Schule mochte Rekursion:

    std::string dreh(std::string str) {
        if (str.length() <= 1) return str;
        return dreh(str.substr(1)) + str[0];
    }
    

    Aufgabe für dich: Diskutiere Vor- und Nachteile. Bonusfrage: wäre es sinnvoll, hier std::string_view zu verwenden und/oder sollte man hier irgendwo const& einfügen?



  • @DirkB wahrscheinlich sollte da ein swap rein und wurde vergessen...



  • @HarteWare sagte in Palindromtest mit einem Typ string als Rückgabewert:

    @DirkB wahrscheinlich sollte da ein swap rein und wurde vergessen...

    Ja.

    Sorry, richtig rum:

    std::string dreh(std::string str)
    {
        auto laenge{ str.length() };
        for (std::size_t i{}; i * 2 < laenge; ++i)
            std::swap(str[i], str[laenge - i - 1]);
        return str;
    }
    

    noch zufußer (guckst Du Dreieckstausch):

    std::string dreh(std::string str)
    {
        auto laenge{ str.length() };
        for (std::size_t i{}; i * 2 < laenge; ++i) {
            auto temp{ str[i] };
            str[i] = str[laenge - i - 1]);
            str[laenge - i - 1]) = temp;
        }
        return str;
    }
    

    peinlich, peinlich 😞

    PS: Wahrscheinlich sollte man decltype(laenge) i{} nehmen wenn man schon auto laenge{ str.length() }; schreibt.



  • @Swordfish Neulich hat hier ein Forenmitglied Schulnoten verteilt. 😉



  • @DirkB Ja, der Faux-pas gibt ne glatte 5. 😉


Anmelden zum Antworten