将递归转换为迭代

问题描述 投票:0回答:2

如何将此代码转换为使用 while 循环而不是递归?

void game(void)
{
    int answer;
    printf("%s", Questions[level]);
    scanf("%d", &answer);
    if (level < 8) {
        if (is_right(level, answer)) {
            printf("Good Job!\n");
            level += 1;
            game();
        }
        else {

            printf("Sorry, you got the wrong answer. Try Again! \n");

            sleep(1);
            system("clear");
            level = 0;

            game();
        }
    }
    else {
        printf("Great Job, You Won!");
    }
}

我尝试从 while 循环开始并尝试向后工作,但我迷失在代码的海洋中

c recursion iteration
2个回答
0
投票

你的程序中有一些奇怪的事情,我稍后会再讨论,但首先,让我们关注这个问题:

如何将此代码转换为使用 while 循环而不是递归?

有很多方法可以做到这一点...

当前的递归调用,即

game();
,不带参数,也不使用返回值。因此,摆脱递归并保持完全相同的功能的一个非常简单的方法可能是:

  1. 在所有现有代码周围添加一个

    while(1)
    循环

  2. continue;
    语句替换当前的递归调用

  3. 当循环要终止时添加

    break;
    语句

看起来像:

void game(void)
{
    while(1) {        // Add a while loop
        int answer;
        printf("%s", Questions[level]);
        scanf("%d", &answer);
        if (level < 8) {
            if (is_right(level, answer)) {
                printf("Good Job!\n");
                level += 1;
                // game();
                continue;  // Start a new round of the game
            }
            else {

                printf("Sorry, you got the wrong answer. Try Again! \n");

                sleep(1);
                system("clear");
                level = 0;

                //game();
                continue;  // Start a new round of the game
            }
        }
        else {
            printf("Great Job, You Won!");

            break; // End the game by breaking out of the while loop
                   // This could also be a return; statement
        }
    }
}

上述解决方案保留了原始程序的结构。如果我们允许一些(小的)重组,我们可以做得更好一点。

void game(void)
{
    while(1) {
        int answer;
        printf("%s", Questions[level]);
        scanf("%d", &answer);

        // Check if the game has finished
        if (level >= 8) {
            printf("Great Job, You Won!");
            return;  // or break;
        }

        if (is_right(level, answer)) {
            printf("Good Job!\n");
            level += 1;
        } else {
            printf("Sorry, you got the wrong answer. Try Again! \n");
            sleep(1);
            system("clear");
            level = 0;
        }
    }
}

上述版本不是检查“游戏是否继续”,而是检查“游戏已完成”,如果是,则返回。通过这样做,我们不再需要显式的

continue;
语句。

现在回到程序中的“奇怪”的事情:

  1. 当用户赢得游戏时(即

    level
    达到8),代码仍会再问一个问题,一旦输入答案,程序就会结束。 这可能不是故意的...

  2. 此外,完成游戏的唯一方法就是赢得游戏(即连续多次回答正确)。我希望用户能有一种方式说“我放弃”

最后,您的代码存在严重问题,可能会导致程序崩溃或无限循环等错误。一定要检查

scanf
的返回值! (见尾注

解决这些问题并进行更多的重组可能会产生如下计划:

void game(void)
{
    level = 0;   // Assuming a new game always starts a level zero

    while(1) {
        int answer;
        printf("%s", Questions[level]);
        if (scanf("%d", &answer) != 1) {
            // Wrong input or input error

            // Add error handling... but for now, just terminate
            exit(1);
        }

        // Let the user end the program with a negative input
        if (answer < 0) {
            printf("Sorry to see you leave before finishing the game. Bye.\n");
            return 0;
        }

        if (is_right(level, answer)) {
            printf("Good Job!\n");
            level += 1;

            // Check if the game has finished
            if (level == 8) {
                printf("Great Job, You Won!");
                return;
            }
        } else {
            printf("Sorry, you got the wrong answer. Try Again! \n");
            sleep(1);
            system("clear");
            level = 0;
        }
    }
}

尾注:

虽然确实应该检查

scanf
的返回值,但更好的建议是:

切勿使用

scanf

表面上

scanf
看起来是一种获取用户输入的简单方法,但事实是它有很多陷阱,只有真正的专家才能使用它(他们可能不会)。以(不正确使用)
scanf
为问题根本原因的 SO 问题数量非常多。他们不断地来......

所以忘记你曾经听说过

scanf
。如果您确实喜欢
scanf
的功能,那么通过使用
fgets
sscanf
,您(几乎)总是会做得更好。


-1
投票

很难称之为递归。

void game(void)
{
    int answer;

    while (level < 8) 
    {
        printf("%s", Questions[level]);
        if(scanf("%d", &answer) != 1){ /* handle error */}        
        if (is_right(level, answer)) 
        {
            printf("Good Job!\n");
            level += 1;
        }
        else 
        {
            printf("Sorry, you got the wrong answer. Try Again! \n");
            sleep(1);
            system("clear");
            level = 0;
        }
    }
    printf("Great Job, You Won!");
}

© www.soinside.com 2019 - 2024. All rights reserved.