Liste mit beliebig langen Stellen



  • rüdiger schrieb:

    edit: arg. war zu langsam. Hab zu lange nachgedacht ob es einen schlauen Weg für exp10 gibt 😃

    Das ist ja wie Blitzschach hier. :xmas1:



  • VirusMaker schrieb:

    nicht maximal, sondern mindestens 10 stellen solls können!

    ⚠ 26^10 = 141.167.095.653.376 ⚠



  • #include <stdio.h>
    unsigned long long int hoch26(int x){
    	unsigned long long int r;
    	for (r = 1; x>0; x--) r*=26;
    	return r;
    }
    
    int main(){
    	printf("%d\n", sizeof(unsigned long long int));
    	int stellen;
    	scanf("%d", &stellen);
    	unsigned long long int grenze = hoch26(stellen);
    	for (unsigned long long int i = 0; i<grenze; i++){
    		for (int j = stellen-1; j>=0; j--)
    			printf("%c", 'a'+(char)(i/hoch26(j)%26));
    		printf("\n");
    	}
    	return 0;
    }
    

    Funktioniert bis 13 Stellen. Überprüfe vorher ob als erstes eine 8 ausgegeben wird. Wenn es eine 4 ist gehts so nicht, wenn es eine 16 ist probiere es mit einem long weniger.

    Ist in vernünftiger Zeit aber eh nicht ausgebbar.

    Wenn du unbegrenzt viele Stellen willst solltest du wirklich ein Zählwerk benutzen.

    Edit: 2^64 > 26^13



  • muss das so kompliziert sein?

    ich dachte da eher an ein groß genuges Feld von chars, das mit AAA... initialisiert wird, und dann mit einer Anzahl-Variable abgeschnitten wird...

    und dann bräuchte ich nur noch ein Zählwerk, damit ich das übergeben kann!

    ginge das nicht so, und wenn ja, wie dann in c?

    mfg



  • #include <stdio.h>
    #include <stdlib.h>
    int main(){
    	int stellen;
    	scanf("%d", &stellen);
    	char *zahl = (char*) malloc(stellen+1);
    	for (int i = 0; i<stellen-1; i++) zahl[i] = 'a'; //zahl mit a's initialisieren
    	zahl[stellen-1] = 'a'-1; //vorher anfangen weil zuerst hochgezählt wird
    	zahl[stellen] = '\0'; //braucht man damit printf weiß wo schluss ist
    	int position = 0; //aktuelle ziffer in zahl
    	while (position>=0){ //Zählwerk zählt bis wir einen Überlauf über die letzte Stelle haben
    		for (position = stellen-1; position>=0; position--){ //wir gehen Ziffernweise durch, erhöhen die Ziffer und kucken ob wir einen Überlauf haben
    			if (zahl[position]=='z'){ //überlauf
    				zahl[position] = 'a'; //ziffer resetten
    				continue; //nächste ziffer erhöhen
    			}
    			else{ //kein überlauf
    				zahl[position]++; //ziffer erhöhen
    				printf("%s\n", zahl); //ziffer ausgeben
    				break; //schleife abbrechen, keine weiteren ziffern müssen erhöht werden
    			}
    		}
    	}
    }
    

    Klappt bis 2147483647 Stellen. Aber 2GB 26^2147483647 mal auf der Konsole ausgeben sollte man vielleicht lassen.

    Man kann übrigens mal eine 1456 oder so eingeben, klappt 😉



  • VirusMaker schrieb:

    muss das so kompliziert sein?
    ...
    ginge das nicht so, und wenn ja, wie dann in c?

    Kannste das Zählwerk von 22:36 während des Wochenendes aufbohren, daß es auch Buchstaben kann?
    Der Code geht aber nur, wenn Du GCC benutzt und nicht mit Microsoft. Bei MS müßtest Du den Speicher mit malloc anlegen.
    Oh, nwp hat aufgerüstet.



  • So, ich habs nun geschaft:

    sA ist die Länge des Strings und schw ist der String mit A..Z initialisiert!
    
    int done=0,done2=0;
    	while(done==0)
    	{
        	done2=0;
    
        	for(int m=sA-1;m>=0&&done2==0;m--)
        	{
            	if(schw[m]<'Z')
            	{
                	schw[m]=look(schw,schw[m]);
                	done2=1;
            	}  
            	else 
            	{
                	//schw[m]='A';
                	schw[m]=look(schw,'A'-1);
            	}
        	}
        	if(schw[0]=='Z') done=1;
    	}
    	of.close();
    }
    
    char look(char schw[26],int m)
    {
    	register char a=m-1;
    	int gef;
    
    	do
    	{
        	gef=0;
        	a++;
            	for(register int y=sA-1;y>=0;y--)
                	if(schw[y]==a)
                	{
                    	gef=1;
                	}
    	}
    	while(gef==1);
    
    	return a;
    }
    

    einzige problem, das er wenn man 5 annimmt, er ABCDE ausgibt, wie gewünscht, aber dass er 2 buchstaben nie wechselt! also nach A an erster Stelle kommt immer E und nicht B 😞

    Was ist falsch?

    mfg



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



  • oder sowas:

    #include <stdio.h>
    
    #define LENGTH 100 // laenge des 'strings'
    #define LIMIT 35  // zeichensatzlaenge-1
    
    char mem[LENGTH];  // speicher
    char *digits = "0123456789abcdefghijklmnopqrstuvwxyz";  // zeichensatz
    
    void count (char *p)
    {
       if (p < mem)
          return;
       (*p)++;
       if (*p > LIMIT)
       {    
          *p = 0;
          count (p-1);
       }
    }
    
    int main()
    {
       char *p;
       for (;;)
       {
          // ausgeben
          p = mem;
          while (p < mem+LENGTH)
              putchar (digits[*p++]);
          puts ("");
    
          // zaehlen
          count (mem+LENGTH-1);
       }
    }
    

    ^^ ohne malloc, beliebige länge und zeichensatz frei definierbar *fg*
    🙂



  • laß den benutzer schon die stellenzahl eingeben.



  • volkard schrieb:

    laß den benutzer schon die stellenzahl eingeben.

    kann er doch, er brauch nur 'nen c-compiler *fg*
    ne, ist ja nur 'ne demo, kann man natürlich leicht umbauen, dass der user die stellenzahl eingeben darf.
    🙂



  • ;fricky schrieb:

    volkard schrieb:

    laß den benutzer schon die stellenzahl eingeben.

    kann er doch, er brauch nur 'nen c-compiler *fg*
    ne, ist ja nur 'ne demo, kann man natürlich leicht umbauen, dass der user die stellenzahl eingeben darf.
    🙂

    mach das doch mal kurz.



  • 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


Anmelden zum Antworten