String mit alphabetisch geordneten Substring


  • Gesperrt

    An für sich ist es mit std::string doch recht einfach, hier wäre meine Herangehensweise:

    #include <iostream>
    #include <string>
    
    std::string getLongest(std::string str)
    {
        int32_t a[4] = {0};
        for (int i = 0; i < str.length() - 1; i++)
        {
            if (str[i] <= str[i + 1])
            {
                a[0]++;
                if (a[0] > a[1])
                {
                    a[1] = a[0];
                    a[2] = a[3];
                }
            }
            else
            {
                a[0] = 0;
                a[3] = i;
            }
        }
        if (a[1])
            return str.substr(a[2] + 1, a[1] + 1);
        else
            return "";
    }
    
    int main()
    {
        std::cout << getLongest("kotafgovlav") << std::endl;
        std::cout << getLongest("dcba") << std::endl;
    }
    

    Wobei ich nicht genau weiß, was passieren soll, wenn ein string keine aufeinanderfolgende Zeichen enthält...


  • Mod

    Ich weiß jetzt nicht, ob man die Kinder davor warnen soll, das nicht zuhause nachzumachen, oder ob das offensichtlich ist.


  • Gesperrt

    @SeppJ sagte in String mit alphabetisch geordneten Substring:

    Ich weiß jetzt nicht, ob man die Kinder davor warnen soll, das nicht zuhause nachzumachen, oder ob das offensichtlich ist.

    Ok 😂 Was wäre dMn. denn besonders schlimm?



  • @EinNutzer0 sagte in String mit alphabetisch geordneten Substring:

    Ok Was wäre dMn. denn besonders schlimm?

    Alles.

    • Du postest eine Lösung mit C++, wo die Frage doch um C geht. Thema verfehlt.
    • Deine Lösung ist brrrr
    • Variablennamen: a[4] - was soll das? Das ist semantisch kein Array, sondern 4 verschiedene Variablen. Also gib diesen Namen! Das ist das allerschlimmste, sogar noch schlimmer als der Leerstring-Fehler!
    • Parameterübergabe von std::string by value?
    • Was, wenn getLongest mit dem Leerstring aufgerufen wird?

  • Mod

    Als zweite Meinung dazu: wob hat absolut Recht, welchen Punkt er fett als allerschlimmsten hervorgehoben hat. Das alleine führt zur sofortigen Disqualifikation.



  • und kommentare fehlen auch noch!


  • Mod

    @Wade1234 sagte in String mit alphabetisch geordneten Substring:

    und kommentare fehlen auch noch!

    Ernsthafte Frage: Würdest du wirklich sagen, mein Code oben braucht Kommentare? Wenn ja, welche?



  • @Wade1234 sagte in String mit alphabetisch geordneten Substring:

    und kommentare fehlen auch noch!

    Sind Variablen gut benannt und die Funktionen kurz, erübrigen sich häufig Code-Kommentare. Daher lese ich lieber Code ohne Kommentare mit gut benannten Variablen als kommentierten Code mit schlecht benannten Variablen. Außerdem passiert es schnell, dass Kommentare nicht mehr stimmen. Beim Ändern von Code muss man auch höllisch aufpassen, weil Kommentare auch deutlich vor oder hinter einer Änderung vorkommen können.

    Einzig die Funktion selbst sollte gut dokumentiert sein, denn aus getLongest kann man nicht ablesen, was es tut. Wie wäre es mit longestOrderedSubstring(string, Compare=std::less) oder ähnlich - meinetwegen hier auch erstmal longestAscendingSubstring(string)? Auf jeden Fall verdient jede Funktion, die keine kleine Helper-Funktion ist, eine Beschreibung ihrer Funktion und ihrer Ein- und Ausgabewerte.



  • @SeppJ sagte in String mit alphabetisch geordneten Substring:

    Ernsthafte Frage: Würdest du wirklich sagen, mein Code oben braucht Kommentare? Wenn ja, welche?

    Das first_ordered_subsequence_length() nicht mit dem Leerstring aufgerufen werden darf würde ich hier kommentieren...



  • @LeMace Warum ist das Ergebnis nicht einfach 0? Bzw. der Leerstring? (je nachdem, ob du die Länge oder den String selbst haben willst) Es wäre überraschend, wenn diese Funktion die Anforderung "kein Leerstring" hätte.



  • @wob
    Ich rede von folgender Funktion:

    size_t first_ordered_subsequence_length(const char *sequence)
    {
      char previous_char = *++sequence;
      size_t length = 1;
      while(*sequence)
        {
          char current_char = *sequence;
          if (current_char >= previous_char)
            length += 1;
          else
            return length;
          previous_char = current_char;
          ++sequence;
        }
      return length;
    }
    

    Wenn die mit "" aufgerufen wird rödelt die while-Schleife doch im Nirvana rum. Oder übersehe ich da etwas?



  • Und das könnte man nicht durch ein einfaches if (!*sequence) return 0; beheben? Oder indem man previous_char und length beide auf 0 setzt und dann gleich in die while-Schleife geht?


  • Mod

    Es ist halt eine interne Funktion, die nicht für den Aufruf durch Anwender gedacht ist. Innerhalb eines einzelnen Codeblocks ist das etwas schwer kenntlich zu machen, aber im Header würde nur die andere Funktion stehen. Innerhalb meiner "Library" kann ich natürlich sicherstellen, dass meine eigenen Annahmen nicht verletzt sind.



  • @SeppJ Deshalb würde ich das "nur" über einen Kommentar lösen. Damit die Kollegen das sofort sehen können.



  • @SeppJ sagte in String mit alphabetisch geordneten Substring:

    @Wade1234 sagte in String mit alphabetisch geordneten Substring:

    und kommentare fehlen auch noch!

    Ernsthafte Frage: Würdest du wirklich sagen, mein Code oben braucht Kommentare? Wenn ja, welche?

    schwierig, vielleicht würde ich in zeile 8 neben dem schleifenkopf irgendwie schreiben, dass in der schleife das momentane zeichen mit dem nächsten zeichen verglichen wird, um die anzahl der geordneten zeichen zu ermitteln, oder in zeile 27, dass die gesamte zeichenkette nach geordneten zeichenketten durchsucht und die position der längsten herausgesucht wird.
    also ich musste da schon so einige zeit überlegen, was da eigentlich gemacht werden soll. dass dinge wie a = 8; //weise a den wert 8 zu totaler quatsch sind, ist mir schon klar, aber bei blöcken hilft das schon beim verständnis.


  • Gesperrt

    Ihr habt völlig recht gehabt mit dem Leerstring... und so wäre es perfekt:

    #include <iostream>
    #include <string>
    
    std::string getLongest(const std::string &str)
    {
        int32_t a[4] = {0};
        for (size_t i = 1; i < str.length(); i++)
        {
            if (str[i - 1] <= str[i])
            {
                a[0]++;
                if (a[0] > a[1])
                {
                    a[1] = a[0];
                    a[2] = a[3];
                }
            }
            else
            {
                a[0] = 1;
                a[3] = i;
            }
        }
        return str.substr(a[2], a[1]);
    }
    
    int main()
    {
        std::cout << getLongest("") << std::endl;
        std::cout << getLongest("kotafgovlav") << std::endl;
        std::cout << getLongest("dcba") << std::endl;
    }
    

    Ich hab mich bewusste gegen lange, sprechende, lokale Variablennamen entschieden, weil diese hierbei unnütz wären.



  • @EinNutzer0 sagte in String mit alphabetisch geordneten Substring:

    Ich hab mich bewusste gegen lange, sprechende, lokale Variablennamen entschieden, weil diese hierbei unnütz wären.

    der grund, warum du solche aufgaben programmierst, besteht darin, das programmieren zu erlernen. da geht es weniger darum, irgendeine lösung für ein problem zu entwickeln, und mehr darum, diese sauber, übersichtlich, verständlich und nachvollziehbar zu erstellen, d.h. vernünftig einrücken, vernünftig kommentieren, vernünftige funktions- und variablennamen, vernünftiger programmablauf usw.. es ist nur mit viel rätselraten zu erkennen, was du in zeile 14 und zeile 20 eigentlich machst und wenn das array dann auch noch a heißt, wird das ganze noch komplizierter.

    wenn du das verstehst, ist es schön, im berufsleben wirst du irgendwann ein besseres angebot mit doppeltem gehalt bekommen, und irgendjemand anderes muss dann damit weiterarbeiten, oder du wirst vor so ein projekt gesetzt und ärgerst dich damit ab.



  • @wob sagte in String mit alphabetisch geordneten Substring:

    @Wade1234 sagte in String mit alphabetisch geordneten Substring:

    und kommentare fehlen auch noch!

    Sind Variablen gut benannt und die Funktionen kurz, erübrigen sich häufig Code-Kommentare. Daher lese ich lieber Code ohne Kommentare mit gut benannten Variablen als kommentierten Code mit schlecht benannten Variablen.

    wenn du aber für jede teilaufgabe eine extra funktion erstellst, stehst du irgendwann vor einem unübersichtlichen berg aus funktionen. deshalb ist es manchmal sinnvoll, mehrere aufgaben in einer funktion unterzubringen und jeder aufgabe eine überschrift zu verpassen.

    Außerdem passiert es schnell, dass Kommentare nicht mehr stimmen. Beim Ändern von Code muss man auch höllisch aufpassen, weil Kommentare auch deutlich vor oder hinter einer Änderung vorkommen können.

    also ähm dokumentation macht 2/3 der arbeit aus, oder wie war das?


  • Gesperrt

    ok, +1 dafür. aber wenn man dabei wirklich jedes if und jedes else kommentieren würde, würde das das alles sehr aufblähen.



  • @Wade1234 sagte in String mit alphabetisch geordneten Substring:

    also ähm dokumentation macht 2/3 der arbeit aus, oder wie war das?

    Kommentare sind eine kleine Teilmenge der Dokumentation.