Рекурсия - это всего лишь скрытый способ вложения четырех петель for
. Вот то, что код выглядит
#include <stdio.h>
void sneaky(int depth, int maxDepth, char str[])
{
char c, start;
start = 'a' + depth * 3;
for (c = start; c < start + 3; c++)
{
str[depth] = c;
str[depth+1] = '\0';
if (depth == maxDepth)
printf("%s\n", str);
else
sneaky(depth + 1, maxDepth, str);
}
}
int main(void)
{
char str[5] = { 0 };
sneaky(0, 3, str);
}
Вы также можете решить эту проблему, и подобные комбинаторные задачи, с помощью простого алгоритма подсчета. Алгоритм подсчета эмулирует естественный подсчет, в котором вы увеличиваете наименьшую значащую цифру от 0 до 9. Когда наименьшая значащая цифра обертывает от 9 до 0, увеличивается следующая цифра влево.
То же самое можно сделать для решения проблемы OP. Но в этом случае цифры имеют либо два, либо три возможных значения. И если вы исследуете шаблон в OP, то очевидно, что младшая значащая цифра слева. В структуре
adgj
bdgj
cdgj
aegj
вы можете увидеть, что a
становится b
, b
становится c
, а когда c
обручи обратно a
, то d
становится e
.
Вот код
#include <stdio.h>
#include <stdlib.h>
static char InitialValue[] = { 'y', 'a', 'd', 'g', 'j', 'm', 'p', 's', 'u', 'w' };
static char NextValue[] = { 'b', 'c', 'a', 'e', 'f', 'd', 'h', 'i', 'g',
'k', 'l', 'j', 'n', 'o', 'm', 'q', 'r', 'p',
't', 's', 'v', 'u', 'x', 'w', 'z', 'y' };
static void error(char *msg)
{
fprintf(stderr, "%s\n", msg);
exit(EXIT_FAILURE);
}
int main(void)
{
int i, oldDigit;
char str[12];
// get the input string from the user
printf("Enter the input string: ");
fflush(stdout);
if (scanf("%10s", str) != 1)
error("whatever");
// convert the input string to the corresponding first output string
for (i = 0; str[i] != '\0'; i++)
{
if (str[i] < '0' || str[i] > '9')
error("invalid input string");
str[i] = InitialValue[str[i] - '0'];
}
printf("%s\n", str);
// use a simple counting algorithm to generate the string combinations
for (;;)
{
for (i = 0; str[i] != '\0'; i++)
{
oldDigit = str[i]; // save the current digit
str[i] = NextValue[oldDigit - 'a']; // advance the digit to the next value
if (str[i] > oldDigit) // if the digit did not wrap
break; // then we've got a new string
}
if (str[i] == '\0') // if all the digits wrapped
break; // then we're done
printf("%s\n", str); // output the new string
}
return(EXIT_SUCCESS);
}
Простым решением грубой силы является использование вложенных циклов. –
@JoachimPileborg: Вложенные циклы в порядке, если у вас всегда есть четыре цифры. Думаю, рекурсия - лучшее решение. –
@MOehm Да, рекурсия, вероятно, лучшее решение, особенно для общего случая. Однако у многих новичков, как правило, возникают проблемы с рекурсией в начале, поэтому, если количество цифр известно с самого начала, то вложенные циклы являются самым простым решением. –