Alle Möglichkeiten ausgeben



  • Hallo miteinander.

    Ich möchte ein Programm schreiben das alle Möglichkeiten für die Kombination

    Vokal Konsonant Vokal Konsonant Vokal .....
    

    ausgibt.
    Doch bisher habe ich bis auf 2 Arrays für Vokale und Konsonanten und eine Schleife die angibt, wieviele Stellen ich berechnen will nicht viel hinbekommen.
    Ich komme einfach auf keinen Ansatz, ich habe zwar bisher an etwas an Rekursion gedacht, will aber einfach nicht darauf kommen, wie ich anfangen soll.
    Ein kleiner Schubs in die richtige Richtung wäre nett 🙂



  • for(std::size_t i = 0; i < Vokale.size(); i++)
      for(std::size_t j = 0; j < Konsonanten.size(); j++)
        std::cout << Vokale[i] << " " << Konsonanten[j] << "\n";
    


  • Damit kann ich nur zwei Stellen berechnen.
    Aber was muss ich anstellen, damit ich von 1-10 Stellen alle berechnen kann?
    Dafür kommt mir kein Ansatz.



  • #include <iostream>
    
    char vowels[] = "aeiou";
    char consonants[] = "bcdfghjklmnpqrstvwxyz";
    
    void print_permutations(int length, char * buff = 0, char * start = 0)
    {
        if (!length)
        {
            if (start)
                std::cout << start << std::endl;
            return;
        }
        char * buffer = buff ? buff : new char [length + 1];
        start = start ? start : buffer;
        for (char * p = (length % 2 ? consonants : vowels); *p; ++p)
        {
            *buffer = *p;
            print_permutations(length - 1, buffer + 1, start);
        }
        if (!buff)
            delete[] buffer;
    }
    
    int main(void)
    {
        print_permutations(10);
    }
    


  • @DrakoXP Bei einem C-Code kann man kein new oder delete aufrufen. Und es sollte printf statt cout heissen...



  • seit wann is das C Code?



  • DrakoXP schrieb:

    seit wann is das C Code?

    Seit du keinen std::string für die Zeichenkettenverarbeitung verwendest.



  • Danke Drako, ich werde versuchen da mal was durchzublicken.
    Allerdings gibt Ideone einen Runtimeerror (sehr wahrscheinlich wegen Endlosrekusion) und auch ansonsten nicht wirklich das gewünschte aus.
    http://ideone.com/wdD2e



  • Anfängernoob schrieb:

    Danke Drako, ich werde versuchen da mal was durchzublicken.
    Allerdings gibt Ideone einen Runtimeerror (sehr wahrscheinlich wegen Endlosrekusion) und auch ansonsten nicht wirklich das gewünschte aus.
    http://ideone.com/wdD2e

    Der Runtimeerror ist, weil das Programm zu lange dauert. Bei 10 Buchstaben gibt es zu viele Kombinationen, ideone bricht offenbar das Prgramm irgendwann ab.
    Mit 4 Buchstaben (klick) sieht das schon viel besser aus.



  • @EOutOfResources:

    std::string hielt ich hier für unangemenessen:

    Für Konsonanten und Vokale zum einen, da es im logischen Sinne nicht um Zeichenketten geht.
    Ich hätte auch einfach char arrays nehmen können,
    hätte dann aber auch die Länge mit angeben müssen...
    war also einfach eine abkürzung...

    Für den Puffer hätten std::string's sinnlosen Performance overhead erzeugt,
    wegen unnötiger Allokationen und Kopien...

    Desweiteren heißt C++ zu Programmieren nicht, dass man immer auf Teufel komm raus Standard-Bibliothek Klassen verwenden muss.
    C++ als Multiparadigmen-Sprache sollte man der Situation angemessen verwenden.



  • DrakoXP schrieb:

    Desweiteren heißt C++ zu Programmieren nicht, dass man immer auf Teufel komm raus Standard-Bibliothek Klassen verwenden muss.
    C++ als Multiparadigmen-Sprache sollte man der Situation angemessen verwenden.

    Gib Dir keine Mühe. DAS werden manche hier nicht mehr lernen ...



  • Ich finde es in solchen Fällen übersichtlicher, die Verwaltung in eine Kopffunktion auszulagern - zumal man sich damit die ganzen Prüfungen ersparen kann, was bei einem exponentiell skalierenden Algorithmus (126 * (105n/2 - 1) / 104 + 1 Funktionsaufrufe) nicht zu verachten ist. Dann lässt sich auch std::string ohne Kopien verwenden:

    #include <cstddef>
    #include <iostream>
    #include <string>
    
    void print_combos_rec(std::string &data, std::size_t pos) {
      static char const *const vowels     = "aeiou";
      static char const *const consonants = "bcdfghjklmnpqrstvwxyz";
    
      if(pos == data.size()) {
        std::cout << data << '\n';
      } else {
        for(char const *p = pos % 2 == 0 ? consonants : vowels; *p; ++p) {
          data[pos] = *p;
          print_combos_rec(data, pos + 1);
        }
      }
    }
    
    void print_combos(std::size_t len) {
      std::string buffer(len, ' ');
      print_combos_rec(buffer, 0);
    }
    
    int main() {
      print_combos(4);
    }
    

    So oder so ist aber aufgrund der schieren Menge an Lösungen eine zweistellige Länge völlig unrealistisch - schon bei einer Länge von 10 gibt es über 12 Milliarden Lösungen, für die über 15 Milliarden mal die Funktion durchlaufen werden müsste.


Anmelden zum Antworten