Liste mit beliebig langen Stellen



  • ok, mal eine interaktive version:

    #include <stdio.h>
    
    #define LIMIT 35  // zeichensatzlaenge-1
    
    int length; // vom benutzer gewaehlt
    char mem[4096];  // speicher
    char *digits = "0123456789abcdefghijklmnopqrstuvwxyz";  // zeichensatz
    int done; // abbruchflag 
    
    void count (char *p)
    {
       if (p < mem)
       {
          done = 1;
          return;
       }
       (*p)++;
       if (*p > LIMIT)
       {    
          *p = 0;
          count (p-1);
       }
    }
    
    int main()
    {
       retry:
       printf ("wie lang? ");
       scanf ("%d", &length);
       if (length > sizeof (mem))
       {
          printf ("nicht laenger als %d\n", sizeof(mem));
          goto retry;
       }
    
       while (!done)
       {
          // ausgeben
          char *p = mem;
          while (p < mem+length)
              putchar (digits[*p++]);
          puts ("");
    
          // zaehlen
          count (mem+length-1);
       }
    }
    

    ^^ wenn schon benutzerfreundloch, dann sollte man den user auch noch den zeichensatz eingeben lassen.
    🙂



  • Dein Code gefällt mir garnicht.

    char mem[4096];  // speicher
    

    Sowas macht man nicht. Niemals.

    if (length > sizeof (mem)){
        printf ("nicht laenger als %d\n", sizeof(mem));
        goto retry;
    }
    

    😡
    Das hatte ich in dem anderen Thread angesprochen. "Fehler: Programmierer ist zu blöd nen ordentliches Programm zu schreiben". Vom goto ganz zu schweigen.

    3 #define LIMIT 35  // zeichensatzlaenge-1
    7 char *digits = "0123456789abcdefghijklmnopqrstuvwxyz";  // zeichensatz
    

    Böööööööse.

    char digits[] = "0123456789abcdefghijklmnopqrstuvwxyz";  // zeichensatz
    int limit = sizeof(digits)-1;
    

    So gehört sich das.

    Ich frage mich echt ob du jemals mehr als 1000 Zeilen Code geschrieben hast. Das ist in etwa die Grenze wo solcher Code unkontrollierbar wird. Das ist einfach zusammengehackt und erfüllt die Aufgabe nur manchmal, aber man braucht ewig bis man es merkt.

    Dein Kommentar den Nutzer das Alphabet eingeben zu lassen war gut. Und nun?

    char alphabet[142];
    scanf("%s", &alphabet);
    

    Schon mit miserablem Code angefangen, da kann man auch gleich so weitermachen.
    Oder noch besser:

    #define MAXALPHABET 142
    char alphabet[MAXALPHABET];
    retry2:
    if (scanf("%*s", MAXALPHABET-1, &alphabet)==MAXALPHABET-1){
        fprintf(stderr, "Fehler, eingegebenes Alphabet ist länger als der Programmierer dachte, versuchen Sie's doch nochmal";
        goto retry2;
    }
    

    Wobei ich sagen muss dass das neu versuchen schon Luxus ist, man kann nämlich endlos neu versuchen, es stürzt nicht nach dem 137. mal ab weil der Programmierer dachte es versucht eh niemand mehr als 137 mal. Das muss man noch irgendwie begrenzen, das geht so nicht.

    Ich bleibe dabei, buffer[wirdschonreichen] ist eine ganz schlechte Idee.



  • ^^welch vernichtendes urteil *fg*

    nwp2 schrieb:

    char mem[4096];  // speicher
    

    Sowas macht man nicht. Niemals.

    ist mir auch aufgefallen, 4096 ist viel zu viel. selbst wenn der user nur mit zwei zeichen arbeitet. wie viele atome gibts nochmal schätzungsweise im universum?

    nwp2 schrieb:

    #define LIMIT 35  // zeichensatzlaenge-1
    7 char *digits = "0123456789abcdefghijklmnopqrstuvwxyz";  // zeichensatz
    

    Böööööööse.

    char digits[] = "0123456789abcdefghijklmnopqrstuvwxyz";  // zeichensatz
    int limit = sizeof(digits)-1;
    

    So gehört sich das.

    dann wenigstens: #define LIMIT (sizeof(digits)-1) *fg*
    nee, aber du kannst LIMIT auch kleiner machen (1...sizeof(digits)-1), damit lässt sich das alphabet ganz komfortabel verkleinern:

    ...
    nochmal:
    printf ("basis? ");
    scanf ("%d", &limit);
    if (limit < 1 || limit >= sizeof(digits))
    {
       printf ("zu gross!\n");
       goto nochmal;
    }
    ...
    

    nwp2 schrieb:

    Das ist einfach zusammengehackt

    das ist allerdings wahr.
    🙂



  • nwp2 schrieb:

    Meins magste nich? Hmm. Ich seh nicht durch bei deinem Code, ein paar mehr Kommentare was wo warum passiert wären günstig. Vor allem, was tut denn look?

    mögen 😃
    nö, iwie blick ich (noch) nicht durch 😃

    und look schaut, welcher buchstabe gehört!

    deins werd ich mir aber mal anschauen!

    mfg



  • nwp2 schrieb:

    Ich frage mich echt ob du jemals mehr als 1000 Zeilen Code geschrieben hast. Das ist in etwa die Grenze wo solcher Code unkontrollierbar wird.

    Jetzt ist es raus. Und wir werden nie wieder so viel Code von fricky zu sehen bekommen.



  • So, habs nun ausprobiert!

    Probleme:
    es werden alle von AA-ZZ durchgegangen und nicht AB-YZ!
    Es sollten wirklich alle Buchstaben nur 1 mal ausgegeben werden, und dass in allen möglichen Varianten!

    Ich hoffe, das das jetzt besser erklärt ist von mir 😃

    MFG



  • VirusMaker schrieb:

    Es sollten wirklich alle Buchstaben nur 1 mal ausgegeben werden, und dass in allen möglichen Varianten!

    das widerspricht sich aber mit deinem ersten posting. kein zählwerk? soll's in etwa so aussehen:

    a b c
    a c b
    b a c
    b c a
    c a b
    c b a
    

    (jetzt mal nur als beispiel mit 3 zeichen)?
    🙂



  • ja, ich voll koffer!

    natürlich so freaky!

    und das halt mit a-z, beliebigen stellen, und das keines doppel vorkommt!

    wer das schafft ist echt n pro!

    mfg



  • versuch mal damit:

    #include <stdio.h>
    
    #define FIRST 'a'  // erstes zeichen
    #define LAST 'z'   // letztes zeichen
    #define N (LAST-FIRST+1)  // zeichenbereich 
    #define LIMIT 3  // laenge der ausgabe
    
    unsigned char use[N];
    unsigned res[N];
    
    void mix (int i)
    { 
       int k;
       // ausgabe
       if (i >= LIMIT) 
       {
          for (k=0; k<LIMIT; k++) 
             putchar (res[k] + FIRST);
          puts("");
          return;
       }
       // neu mischen
       for (k=0; k<N; k++)
       { 
          if (use[k] == 0)
          { 
             use[k] = 1; 
             res[i] = k;
             mix (i+1);
             use[k] = 0;
          }
       }
    }
    
    int main()
    { 
       mix(0);  
    }
    

    sorry, nwp2, ist leider wieder ohne malloc *fg*
    🙂



  • nachtrag:

    ;fricky schrieb:

    unsigned char use[N];
    unsigned res[N];

    mach da mal 'int' draus, sonst kriege ich wieder mecker von nwp2.
    🙂



  • ;fricky schrieb:

    mix (i+1);
    use[k] = 0;

    das kann ja iwie nicht funzen!



  • VirusMaker schrieb:

    ;fricky schrieb:

    mix (i+1);
    use[k] = 0;

    das kann ja iwie nicht funzen!

    was geht nicht bei dir? zeig mal fehlermeldungen, oder ist die ausgabe nicht nach deinen wünschen?
    benutzt du einen C++- statt eines C-compilers?
    🙂



  • Hmm, kein Plan was fricky da macht.

    Ich hab da soone Idee.
    Man bastle sich eine rekursive Funktion permutation(char liste[]), die bei nur einem Element in liste nur die liste zurückgibt und ansonsten die liste um 1 kürzt, permutieren lässt und dann das entfernte Element an allen Stellen einsetzt.

    Ich habe das mal in python zusammengehackt:

    alphabet = ["a", "b", "c", "d"]
    def permutationen(liste):
        if len(liste)==1: return [liste] #bei nur einem Element gibt es nur eine Möglichkeit
        else:
            resultat = [] #sammelliste für permutationen
            for l in permutationen(liste[1:]): #das erste element sparen wir uns und packen es dann an alle stellen
                for i in range(0, len(liste)): #i ist die stelle an der das element eingefügt werden soll
                    r = l[:i]
                    r.extend(liste[0])
                    r.extend(l[i:])
                    resultat.append(r)
        return resultat
    
    for liste in permutationen(alphabet):
        print liste
    

    Da kommt dann sortiert sowas raus:

    ['a', 'b', 'c', 'd']
    ['a', 'b', 'd', 'c']
    ['a', 'c', 'b', 'd']
    ['a', 'c', 'd', 'b']
    ['a', 'd', 'b', 'c']
    ['a', 'd', 'c', 'b']
    ['b', 'a', 'c', 'd']
    ['b', 'a', 'd', 'c']
    ['b', 'c', 'a', 'd']
    ['b', 'c', 'd', 'a']
    ['b', 'd', 'a', 'c']
    ['b', 'd', 'c', 'a']
    ['c', 'a', 'b', 'd']
    ['c', 'a', 'd', 'b']
    ['c', 'b', 'a', 'd']
    ['c', 'b', 'd', 'a']
    ['c', 'd', 'a', 'b']
    ['c', 'd', 'b', 'a']
    ['d', 'a', 'b', 'c']
    ['d', 'a', 'c', 'b']
    ['d', 'b', 'a', 'c']
    ['d', 'b', 'c', 'a']
    ['d', 'c', 'a', 'b']
    ['d', 'c', 'b', 'a']

    Ist es das was du wolltest?

    In C kann man nicht so schön mit Listen hantieren, aber der Algorithmus sollte klar sein.



  • nwp2 schrieb:

    Ich habe das mal in python zusammengehackt:

    alphabet = ["a", "b", "c", "d"]
    def permutationen(liste):
        if len(liste)==1: return [liste] #bei nur einem Element gibt es nur eine Möglichkeit
        else:
            resultat = [] #sammelliste für permutationen
            for l in permutationen(liste[1:]): #das erste element sparen wir uns und packen es dann an alle stellen
                for i in range(0, len(liste)): #i ist die stelle an der das element eingefügt werden soll
                    r = l[:i]
                    r.extend(liste[0])
                    r.extend(l[i:])
                    resultat.append(r)
        return resultat
    
    for liste in permutationen(alphabet):
        print liste
    

    Da kommt dann sortiert sowas raus:

    ['a', 'b', 'c', 'd']
    ['a', 'b', 'd', 'c']
    ['a', 'c', 'b', 'd']
    ['a', 'c', 'd', 'b']
    ['a', 'd', 'b', 'c']
    ['a', 'd', 'c', 'b']
    ['b', 'a', 'c', 'd']
    ['b', 'a', 'd', 'c']
    ['b', 'c', 'a', 'd']
    ['b', 'c', 'd', 'a']
    ['b', 'd', 'a', 'c']
    ['b', 'd', 'c', 'a']
    ['c', 'a', 'b', 'd']
    ['c', 'a', 'd', 'b']
    ['c', 'b', 'a', 'd']
    ['c', 'b', 'd', 'a']
    ['c', 'd', 'a', 'b']
    ['c', 'd', 'b', 'a']
    ['d', 'a', 'b', 'c']
    ['d', 'a', 'c', 'b']
    ['d', 'b', 'a', 'c']
    ['d', 'b', 'c', 'a']
    ['d', 'c', 'a', 'b']
    ['d', 'c', 'b', 'a']

    Das wäre in C++ mit fricky-Erweiterungen

    #include <stdio.h>
    #include <algorithm>
    
    #define FIRST 'a'  // erstes zeichen
    #define LAST 'z'   // letztes zeichen
    #define N (LAST-FIRST+1)  // zeichenbereich
    #define LIMIT 5  // laenge der ausgabe
    
    unsigned char use[N];
    
    int main()
    {
    	for(int i=0;i<LIMIT;++i)
    		use[i]=FIRST+i;
    	do
    		printf("%s\n",use);
    	while(std::next_permutation(use,use+LIMIT));
    }
    

    und rauskommen tut

    abcd
    abdc
    acbd
    acdb
    adbc
    adcb
    bacd
    badc
    bcad
    bcda
    bdac
    bdca
    cabd
    cadb
    cbad
    cbda
    cdab
    cdba
    dabc
    dacb
    dbac
    dbca
    dcab
    dcba
    

    nwp2 schrieb:

    Ist es das was du wolltest?

    Ja, das ist hier die Frage.



  • volkard schrieb:

    Das wäre in C++ mit fricky-Erweiterungen...

    damit die fricky-erweiterung eure outputs erzeugt, müsst ihr sie so parametrisieren:

    #define FIRST 'a'  // erstes zeichen
    #define LAST 'd'   // letztes zeichen
    #define N (LAST-FIRST+1)  // zeichenbereich 
    #define LIMIT N  // laenge der ausgabe
    

    aber mein permutator-hack zählt ja (im beispiel da oben) jede stelle von 'a' bis 'z' durch, hört also, (bei 'ner länge von 3) mit 'xyz' auf, so wie's der OP scheinbar haben will.
    btw, ist sowas auch mit std::next_permutation möglich, oder sollte man dazu doch besser C nehmen *fg*
    🙂



  • EDIT:

    Leute, ihr seit die Besten!!!

    #include <stdio.h>
    #include <algorithm>
    #include <conio.h>
    
    unsigned char use[26]="ABCDEFGHIKLMNOPQRSTUVWXYZ";
    
    int main()
    {
        int stellen;
        printf("Stellen: ");
        scanf("%d",&stellen);
        use[stellen]='\0';
        do
            printf("%s\n",use);
        while(std::next_permutation(use,use+stellen));
        getch();
    }
    

    Mit dem funktionierts!

    THX AN:

    • nwp2 für die Permutions-Idee
    • volkard der mir gezeigt hat, wie mans in C einbaut
    • ;fricky fürs mithelfen

    Ihr seit einfach die besten 👍

    Schöne Weihnachten euch allen :xmas1:



  • VirusMaker schrieb:

    ...volkard der mir gezeigt hat, wie mans in C einbaut

    *räusper* std.next_permutation() gibts nicht in C.
    🙂



  • ;fricky schrieb:

    VirusMaker schrieb:

    ...volkard der mir gezeigt hat, wie mans in C einbaut

    *räusper* std.next_permutation() gibts nicht in C.
    🙂

    echt? aja, klassen gibts ja erst ab C++ -.-

    ist mir aber echt wurscht jetzt 😃
    vielleicht kann ein mod verschieben oder was, ich bin glücklich und zufrieden 😃

    MFG



  • VirusMaker schrieb:

    vielleicht kann ein mod verschieben oder was

    wohin? einen trashcan gibts hier nicht. und im C++ forum werden sie über dich herfallen, weil du printf/scanf statt cout/cin nimmst. *fg*
    wofür brauchst du das eigentlich? hausaufgabe oder nur so zum spass? wenn ersteres, dann poste doch mal den text der aufgabe. deinen vielen widersprüchlichen beschreibungen nach glaube ich nämlich, dass du sie immer noch nicht verstanden hast.
    🙂



  • ;fricky schrieb:

    VirusMaker schrieb:

    vielleicht kann ein mod verschieben oder was

    wohin? einen trashcan gibts hier nicht. und im C++ forum werden sie über dich herfallen, weil du printf/scanf statt cout/cin nimmst. *fg*
    wofür brauchst du das eigentlich? hausaufgabe oder nur so zum spass? wenn ersteres, dann poste doch mal den text der aufgabe. deinen vielen widersprüchlichen beschreibungen nach glaube ich nämlich, dass du sie immer noch nicht verstanden hast.
    🙂

    die erweiterung mach ich nur, um mich weiterzubilden!

    leider gehts so auch nicht, wie ich vorher geschrieben hat 😞 😞 😞
    ich bin im moment voll verzweifelt!
    wie soll ich dass machen?

    also wenn er 5 stellen hat, müsst er doch zuerst die ersten 5 permutieren, dann 6, dann 7 usw, damit er auch alles, wirklich alles permutiert hat 😞

    bitte helft mir 😞

    MFG

    EDIT:

    char schwS[26];
        printf("Anzahl: ");
        scanf("%d",&sA);
        int i=sA;
    
        char schw[26];
        strcpy(schw,"ABCDEFGHIKLMNOPQRSTUVWXYZ");
    
        do
        {
            do
    	    {
                strcpy(schwS,schw);
                schwS[sA]=0;
                printf("%s\n",schw);   
    	    }
            while(std::next_permutation(schw,schw+sA));
    
    //HIER FEHT WAS!?!
    
        } while(schw[0]!='Z'); //es sollte bei 5 mit ZYXWV aufhöhren
    }
    

    soweit hab ichs schonmal


Anmelden zum Antworten