【问题标题】:How do I break out of a recursion in C?如何摆脱C中的递归?
【发布时间】:2014-12-07 17:36:41
【问题描述】:

我还是个编程新手,所以请容忍我糟糕的语法和逻辑,如果有任何不好的话。我一直在用 C 编写一个密码解算器。它从用户那里读取 3 个单词,计算它们的值并将它们打印到屏幕上。 (例如send+more=money -> 9567+1085=10652

我尝试了类似于排列算法的东西。它可以进行计算,但对于某些输入,结果会被打印多次:

如何修改我的代码,以便在第一次处理 if (n1+n2==n3) 下的 printf 命令时递归结束并且程序返回到 main 函数?

/* Swaps the two elements of an array. */
void swap(int v[], int i, int j) {
    int t;
    t = v[i];
    v[i] = v[j];
    v[j] = t;
}

/* Solves the Cryptarithmetic puzzle. */
int solve(int v[], int n, int i, char s1[], char s2[], char s3[], char letters[]) {
    int k, m, j, t = 0, power, n1 = 0, n2 = 0, n3 = 0;
    if (i == n) {
        /*....some codes that 
         * calculate the value of each input word.....*/

        /*This part verifies the values and if they are correct, prints them to screen*/
        if (n1 + n2 == n3) {
            printf("found!\n");
            printf("\n%s :  %6d\n", s1, n1);
            printf("%s :  %6d\n", s2, n2);
            printf("%s :  %6d\n", s3, n3);
        }
    } else
        for (j = i; j < n; j++) {
            swap(v, i, j);
            solve(v, n, i + 1, s1, s2, s3, letters);
            swap(v, i, j);
        }
}

【问题讨论】:

  • 由于您将函数定义为int 类型,因此您需要return 类型为int 的值。返回1,如果没有其他信息表明成功,或者0,如果至少遇到错误。
  • @DavidC.Rankin 我尝试在printf ("%s : %6d\n", s3 , n3); 之后添加return 1;,但没有任何改变。
  • 你把return放在你需要terminate递归的地方。比如i==n 之后会发生什么,或者你完成else for 循环之后会发生什么?请注意,在递归函数中的return 之后,该函数仍将像backs out of the levels of recursion 一样向后迭代。你怎么知道你什么时候完成处理?把退货放在那里...

标签: c recursion cryptarithmetic-puzzle


【解决方案1】:

需要进行三处更改。首先,你需要在解决后返回一些东西:

    printf ("%s : %6d\n", s3 , n3);
    return 1;

接下来需要在递归的时候检查返回值,找到解决办法就停止:

    if (solve (v, n, i+1,s1,s2,s3,letters))
        return 1;

最后,如果没有找到解决方案,需要返回0:

    }
    return 0;
}

【讨论】:

    【解决方案2】:

    您可以使用setjmp()/longjmp()。为此,您需要:

    #include <setjmp.h>
    

    然后是一个全局变量:

    jmp_buf env;
    

    然后在 main(或任何你调用递归函数的地方)你做:

    if(!setjmp(env)) recursiveSolve();
    

    然后当你找到解决方案时:

    if(solutionFound) longjmp(env, 1);
    

    它会像什么都没发生一样返回到 main - 但是找到了您的解决方案。

    【讨论】:

    • 使用 70 吨压力机压扁一只苍蝇! setjmp() / longjmp() 不可掉以轻心。最好让solve() 返回一个成功指示器并在递归调用时对其进行测试。我还给初始调用者一个简单的成功指示符。
    • @chqrlie 一个例外机制是 70 吨压力机,longjmp() 在这种情况下是最轻的事情,当一个人不想像你说的那样做(正确的方式)无论出于何种原因。
    猜你喜欢
    • 2020-06-25
    • 1970-01-01
    • 1970-01-01
    • 2021-09-28
    • 1970-01-01
    • 1970-01-01
    • 2016-02-19
    • 2017-12-19
    • 1970-01-01
    相关资源
    最近更新 更多