Ich stimme den anderen zu, die angegeben haben, dass es am besten wäre, zuerst daran zu arbeiten, die Version mit Loops besser zu machen. Das Verbessern von Namen und Aufteilen von Aufgaben in Funktionen kann viel zur Klarheit Ihres Codes beitragen. Hier ist eine Version, die Schleifen verwendet. Ich habe versucht, die Aufgabe in kleinere Funktionen zu brechen in der Lesbarkeit zu unterstützen:
#include <stdio.h>
#include <stdbool.h>
void show_perms(size_t arr_sz, size_t nr_vals);
void print_perm(size_t arr_sz, int arr[arr_sz]);
bool next_array(size_t arr_sz, int arr[arr_sz], size_t nr_vals);
int main(void)
{
size_t nr_vals;
size_t arr_sz;
printf("Enter number of values: ");
scanf("%zu", &nr_vals);
printf("Enter size of array: ");
scanf("%zu", &arr_sz);
show_perms(arr_sz, nr_vals);
return 0;
}
void show_perms(size_t arr_sz, size_t nr_vals)
{
int arr[arr_sz];
for (int i = 0; i < arr_sz; i++)
arr[i] = 0;
do{
print_perm(arr_sz, arr);
} while (next_array(arr_sz, arr, nr_vals));
}
void print_perm(size_t arr_sz, int arr[arr_sz])
{
for (int i = 0; i < arr_sz; i++)
printf("%d ", arr[i]);
putchar('\n');
}
bool next_array(size_t arr_sz, int arr[arr_sz], size_t nr_vals)
{
int i;
for (i = (arr_sz - 1); i >= 0; i--) {
arr[i] = (arr[i] + 1) % nr_vals;
if (arr[i] != 0)
break;
}
if (i < 0)
return false;
else
return true;
}
Ich schrieb die oben Version zuerst, und verwenden es als Leitfaden in dieser rekursiven Lösung zu konstruieren. Zuerst hatte ich eine boolesche Funktion finished()
, die überprüft, ob die aktuelle Permutation die letzte war, aber dann erkannte ich, dass die Änderung der index
Variable von size_t
zu index
ermöglicht einen Wert von -1 zu halten, nachdem die endgültige Permutation gefunden wurde. Dies vereinfachte den rekursiven Code und zwang mich, die Schleifenlösung erneut zu betrachten, die auch eine Testfunktion namens is_another()
hatte. Ich entfernte diese Funktion und änderte die next_array()
Funktion, um true
zurückzugeben, wenn es mehr Permutationen gibt, und false
wenn nicht (wenn i
negativ ist).
Die rekursive Lösung verwendet zwei gegenseitig rekursive Funktionen zum Erstellen und Drucken der Permutationen. Die Funktion print_permutations()
lässt die Dinge beginnen, indem sie ein Array deklariert und auf Null setzt. Dann wird die print_perm()
-Funktion aufgerufen, wobei zuerst die erste Permutation (alle Nullen) gedruckt wird und dann die next_perm()
-Funktion aufgerufen wird. Diese Funktion ruft sich rekursiv selbst auf, bis die nächste Permutation gefunden wird, an der print_perm()
erneut aufgerufen wird und alles neu beginnt. Dies wird so lange fortgesetzt, bis der Wert index
-1 erreicht, woraufhin der letzte Aufruf an next_perm()
zurückkehrt. Hier
#include <stdio.h>
void print_permutations(size_t arr_sz, size_t nr_vals);
void print_perm(size_t arr_sz, int arr[arr_sz], size_t nr_vals);
void next_perm(size_t arr_sz, int arr[arr_sz], size_t nr_vals, int index);
int main(void)
{
size_t nr_vals;
size_t arr_sz;
printf("Enter number of values: ");
scanf("%zu", &nr_vals);
printf("Enter size of array: ");
scanf("%zu", &arr_sz);
print_permutations(arr_sz, nr_vals);
return 0;
}
void print_permutations(size_t arr_sz, size_t nr_vals)
{
int arr[arr_sz];
for (int i = 0; i < arr_sz; i++)
arr[i] = 0;
print_perm(arr_sz, arr, nr_vals);
}
void print_perm(size_t arr_sz, int arr[arr_sz], size_t nr_vals)
{
for (int i = 0; i < arr_sz; i++)
printf("%d ", arr[i]);
putchar('\n');
next_perm(arr_sz, arr, nr_vals, (arr_sz - 1));
}
void next_perm(size_t arr_sz, int arr[arr_sz], size_t nr_vals, int index)
{
if (index < 0)
return ;
arr[index] = (arr[index] + 1) % nr_vals;
if (arr[index] != 0)
print_perm(arr_sz, arr, nr_vals);
else
next_perm(arr_sz, arr, nr_vals, (index - 1));
}
ist die Ausgabe von einem Probelauf:
Enter number of values: 2
Enter size of array: 3
0 0 0
0 0 1
0 1 0
0 1 1
1 0 0
1 0 1
1 1 0
1 1 1
Wenn Ihre Motivation ein „sauberer“ Look ist, sollten Sie einige Dinge tun, bevor Sie Rekursion prüfen. Verwenden Sie zunächst aussagekräftige Variablennamen, nicht Ein-Buchstaben-Namen. Zweitens, teilen Sie dies in verschiedene Funktionen mit aussagekräftigen Namen auf. Drittens, verwenden Sie die richtige Formatierung/Einrückung. Zum Schluss fügen Sie Kommentare und Unterschriften hinzu.Wenn Sie all dies getan haben, wird es viel einfacher sein, herauszufinden, wie man es in Rekursion umwandelt. – Jameson
Eine zusätzliche Anmerkung, wenn Sie nicht wissen, wie man es rekursiv macht, dann gibt es wenig Beweise, dass es wirklich irgendetwas verbessern wird. Ich werde immer noch sehen, was ich für Sie tun kann – jcolemang
ja, das ist mein Problem, ich bin nicht gut darin, eine rekursive Funktion zu machen, und ich werde es schätzen @jcolemang – TheOne817