String mit alphabetisch geordneten Substring



  • @SeppJ
    Oder unter Berücksichtigung der Groß/Kleinschreibung dann so, oder nicht?

    #include <stdio.h>
    #include <string.h>
    #include <ctype.h>
    
    size_t step_subsequence( const char *sequence )
    {
      if( sequence )
      {
        char previous_char = 0x0;
        size_t length = 0;
        while( *sequence )
        {
          char current_char = toupper( *sequence );
          if( current_char >= previous_char ){ length += 1; }
          else { return length;  }
          previous_char = current_char;
          ++sequence;
        }
        return length;
      }
      return 0;
    }
    
    void get_longest_alpha_sequence( const char *sequence, char *result )
    {
      if( !sequence || !result ){ return; }
      size_t longest_subsequence_length = 0;
      const char *start_longest_subsequence = sequence;
      while( *sequence )
      {
        size_t subsequence_length = step_subsequence( sequence );
        if( subsequence_length > longest_subsequence_length )
        {
          longest_subsequence_length = subsequence_length;
          start_longest_subsequence = sequence;
        }
        sequence += subsequence_length;
      }
      memcpy( result, start_longest_subsequence, longest_subsequence_length );
      result[longest_subsequence_length] = 0;
    }
    
    int main( int argc, char **argv )
    {
      char data[] = "dehnijwdfbre4oto4tmpfe3TaacejkzREHY$%edft3GTE$HTSATSSERgdg";
      char result[sizeof(data)] = { 0 };
      get_longest_alpha_sequence( data, result );
      puts( result );
      return 0;
    }
    

    Dann wird aus

    3Taacejkz
    

    stattdessen

    aacejkz
    

  • Mod

    Mal angenommen, du könntest mich nicht fragen (Ja, schaut richtig aus): Wie würdest du prüfen, ob es wirklich korrekt ist?



  • Danke für eure Lösungen @Wutz @SeppJ @fairiestoy !!! Wobei meine Studienkollegin und ich, den Code von Wutz noch am simpelsten finden und daher schon super!
    Allerdings sind wir ja noch blutiger Anfänger und können eure Lösungen nicht zu 100% verstehen. Daher werden wir sie auch nicht einfach übernehmen.

    @Wutz
    Wieso benutzt du while und if mit unterschiedlichen Zeigern?
    Und was bedeutet z[strlen(z)-1]? Geht hierbei nicht um das Verständnis von z und strlen, sondern wofür stehen die eckigen Klammern? Wird das in den Klammern bevorzugt und danach mit z multipliziert?
    Der Rest ist für uns soweit verständlich!

    Ich möchte wenigstens die Schritte verstehen... auch meine Studienkollegin kommt in der Aufgabe nicht richtig weiter. Ich schicke euch auch nochmal diesen Code, auf ihrer Bitte hin hier rein. Wir haben getrennt voneinander gearbeitet, sodass unterschiedliche Lösungsansätze raus kamen.

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    char * strcpy(char *ergebnis, char *array);
    int main()
    {
        char alpha[27] = "abcdefghijklmnopqrstuvwxyz";      // Alphabet als Abgleich
        int a=0;
        char array[21] = "sakdeidpoidweoidoijk";            // Buchstabensalat
        int i=0;
        char ergebnis[3];
    
    
        for(i=0; i<21; i++)                                 // Durchgang von jedem Buchstaben im Buchstabensalat
        {
            if(array[i] == alpha[a])
            {
                ergebnis[0] = strcpy(ergebnis, array);
                if(array[i+1] == alpha[a]++)
                {
                    ergebnis[1] = strcpy(ergebnis, array);
                    if(array[i+1] == alpha[a]++)
                    {
                        ergebnis[2] = strcpy(ergebnis, array);
                    }
                }
            }
        }
        printf("%s", ergebnis);
    
    
        return 0;
    }
    


  • @Luckyingmar sagte in String mit alphabetisch geordneten Substring:

    Und was bedeutet z[strlen(z)-1]?

    Die [ sind der ganz normale Arrayzugriff. Mit dem Ausdruck greifst du auf das letzte Zeichen im String z zu.

    @Luckyingmar sagte in String mit alphabetisch geordneten Substring:

    ergebnis[0] = strcpy(ergebnis, array);

    Das ist einfach nur Blödsinn. Das kann nicht funktionieren.

    strcpy liefert die Adresse von dem erste Element von ergebnis zurück. Dafür ist in ergebnis[0] kein Platz, zudem wird das gerade Kopierte wieder überschrieben und ergebnis ist auch zu klein (nur 3 Elemente).

    Daher ist eine weiter Erklärung wohl nicht nötig.


  • Mod

    @Luckyingmar sagte in String mit alphabetisch geordneten Substring:

    @Wutz
    Wieso benutzt du while und if mit unterschiedlichen Zeigern?

    Was soll man dazu sagen? Einmal will er halt was über sein s wissen und das andere Mal über sein z.

    Und was bedeutet z[strlen(z)-1]? Geht hierbei nicht um das Verständnis von z und strlen, sondern wofür stehen die eckigen Klammern? Wird das in den Klammern bevorzugt und danach mit z multipliziert?

    char str[] = "abc";
    

    Was wäre str[1]? Das hast du aber schon einmal gesehen? Was wäre str[1+1]? Was wäre str[irgendein total komplizierter Ausdruck, der irgendein Ergebnis hat]?

    Zeile 5 in deinem Programm gewöhnst du dir am besten sofort ab. Umdeklarieren interner Funktionen ist eine der bösesten Sachen, die du machen kannst.

    Feste Werte, die magisch im Programm stehen (z.B. die 21 in Zeile 15) zählen auch zu den schlimmeren Sachen, die man machen kann.

    strcpy habt ihr komplett falsch verstanden.

    Das Programm geht komplett an der Aufgabenstellung vorbei. Und das, was es versucht, macht es auch noch krass falsch. Das kann man gar nicht korrigieren, daher beschränke ich mich auf Tipps, wie man besser programmiert, anstatt darauf einzugehen.

    Das ganze Programm wirkt, als habe jemand irgendwie einen Haufen Zutaten genommen, von denen angenommen wird, dass sie irgendwie dazu gehören könnten, und dann zufällig zusammen geworfen, ohne jedweden Plan. Das funktioniert aber nicht. Code ist nicht irgendein zusammengewürfelter Haufen von Zeichen. Code ist Logik pur. Du musst von jedem einzelnen Zeichen in deinem Programm genau wissen, wo und warum du es setzt.

    Ihr habt es nicht einmal hinbekommen, die Dokumentation von strcpy zu lesen, sondern habt auch hier einfach geraten, dass da irgendwelche Zutaten zugehören, und dann zufällig versucht, dass etwas compilierbares heraus kommt, ohne irgendetwas davon zu verstehen. Das ist symptomatisch für eure Herangehensweise im gesamten Programm und man kann euch nicht helfen, so lange ihr mit diese Denkweise unterwegs seid.


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