Zeichenkette von A bis Z, alle Möglichkeiten durchgehen.
-
Hallo Leute !
Wenn ich eine Zeichenkette habe und alle denkbaren Kombinationen von z.B. A bis Z durchgehen will, kann ich das ja so machen:char arr[] = "AAAAA"; for ( arr[0]='A'; arr[0]<='Z'; arr[0]++ ) { for ( arr[1]='A'; arr[1]<='Z'; arr[1]++ ) { for ( arr[2]='A'; arr[2]<='Z'; arr[2]++ ) { for ( arr[3]='A'; arr[3]<='Z'; arr[3]++ ) { for ( arr[4]='A'; arr[4]<='Z'; arr[4]++ ) { printf("%s\n", arr ); } } } } }
Bloß, hab ich jetzt ne Zeichenkette, die z.B. so aussieht:
char arr2[] "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
Dann bin ich ein wenig gekniffen, nicht wahr ?
Würde ziemlich viele geschachtelte Schleifen ergeben. Geht das auch irgendwie eleganter ?
Bin der Meinung, das hier im Forum schon gesehen zu haben. Das war eine rekursive Funktion. Aber leider finde ich das nicht mehr.
-
Ja, du brauchst ziemlich viele verschachtelte Schleifen - aber weil du deren Verschachtelungstiefe nicht zur Laufzeit anpassen kannst, nehmen wir dazu rekursive Funktionen:
void iterate(char* text,int index) { if(text[index]=='\0') { printf("%s\n",text); } else { for(text[index]='A';text[index]<='Z';++text[index]) { iterate(text,index+1); } } } ... char arr[] = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; //wie lang der Eingabestring wird, ist egal - und er muß noch nicht einmal mit A's initialisiert werden //allerdings könnte bei extrem langen Eingaben dein Programmstack an die Grenzen kommen iterate(arr,0);
-
Hey Mann ging das schnell. Vielen Dank.
Jetzt muss ich erstmal studieren, wie das funktioniert
-
Eine verdammt gute Sache
-
w3rk3r schrieb:
Eine verdammt gute Sache
ja, verdammt gut. es ist aber eher zufall, das es funktioniert.
sozusagen eine zufällige erscheinung der rekursion.
-
verdammt gut schrieb:
ja, verdammt gut. es ist aber eher zufall, das es funktioniert.
Was meinst du mit "ist eher zufall"? Ja, das Programm ist nicht bis zum Ende durchoptimiert, aber trotzdem so weit durchdacht, daß es bewußt so funktioniert und nicht "durch zufall".
(das einzig fragwürdige ist eventuell, daß ich die Schachtelungstiefe implizit durch die Länge des Zielstrings verstecke)
-
was könnte man denn da noch optimieren ?
-
w3rk3r schrieb:
was könnte man denn da noch optimieren ?
z.b. eine variante ohne rekursion verwenden
void update (char *p) { for (;;) { (*p)++; if (*p <='Z') return; *p-- = 'A'; } } void main(void) { char arr[] = "AAAAA"; char *p = arr + strlen(arr)-1; // points to last char for (;;) { puts (arr); update (p); } }
-
hey, total krass.
-
@vista:
Erstens:ich hab das jetzt nicht getestet, aber wenn das tatsächlich die richtige Ausgabe liefert...
Zweitens: Und wie beendest du das Hauptprogramm?
-
CStoll schrieb:
Und wie beendest du das Hauptprogramm?
das einzubauen wollte ich dem OP überlassen.
-
eine abbruchbedingung habe ich jetzt eingebaut.
beide versionen erzeugen die gleiche ausgabe.
aber das problem war eher, mir so etwas selbst einfallen zu lassen.
ich weiss auch gar nicht, ob man so etwas üben kann, dafür bin ich wohl einfach zu blöd.
hut ab vor denjenigen, die sich so etwas einfallen lassen können
-
w3rk3r schrieb:
hut ab vor denjenigen, die sich so etwas einfallen lassen können
das kannst du auch. mit der zeit kriegt man einfach ein auge für sowas.
als kleine übung für dich: programmiere einen 5-stelligen zähler im 26-er stellenwertsystem. damit könnte man die aufgabe auch lösen.
-
hütchenspiel-freak schrieb:
als kleine übung für dich: programmiere einen 5-stelligen zähler im 26-er stellenwertsystem. damit könnte man die aufgabe auch lösen.
mal sehen ob ich eventuell morgen dazu komme, für heute ist die luft raus
ich hab die zweite version etwas verändert, jetzt ist das alles 'unter einem hut' also in einer funktion und nicht mehr aufgeteilt in funktion und hauptprogramm:void iterator( char* p ) { int LEN = strlen(p); int len; char* pc; L1: len = LEN; pc = p + LEN-1; printf("%s\n", p ); while( len-- ) { (*pc)++; if ( *pc<='Z' ) goto L1; *pc-- = 'A'; } }
-
CStoll schrieb:
@vista:
Erstens:ich hab das jetzt nicht getestet, aber wenn das tatsächlich die richtige Ausgabe liefert...
Zweitens: Und wie beendest du das Hauptprogramm?drittens:
void main(void){
oO
-
das hat mir jetzt doch keine ruhe gelassen
war ne gute idee mit der zählerübung. allderdings zum nachvollziehen sind 26 stellen ein bisschen viel für die überschicht, darum habe ich es mit der basis 3 gemacht.void counter5radix3() // 5 stelliger zähler im dreiwertigen zählsystem { int counter[] = {0,0,0,0,0}; int radix = 3; int* p; int N = 3*3*3*3*3; L1: p = counter + 4; printf("%d %d %d %d %d\n", counter[0], counter[1], counter[2], counter[3], counter[4] ); N--; while(N) { (*p)++; if ( *p < radix ) goto L1; *p-- = 0; } }
-
w3rk3r schrieb:
void counter5radix3() // 5 stelliger zähler im dreiwertigen zählsystem { ... int N = 3*3*3*3*3; ...
das gibt bei einer grossen basis aber probleme. diese abbruchbedingung ist nicht empfehlenswert.
-
attention schrieb:
das gibt bei einer grossen basis aber probleme. diese abbruchbedingung ist nicht empfehlenswert.
Ja, ich weiss. Mir fiel zu diesem Zeitpunkt nichts besseres ein.
Einwhile( p>=counter )
ist da schon viel eleganter.