Java 学习和理解递归语句的最佳方法是什么?

Java 学习和理解递归语句的最佳方法是什么?,java,recursion,Java,Recursion,我很难阅读和理解java中的递归语句 如果我的教授向我们展示代码并问这是做什么的?它会返回什么?…我发现自己盯着代码,好像它最终会有意义…但它从来没有 例如-- public static Int mystery(int[][] a, int b) { int x = 0; for (int i = 0; i < a.length; i++){ for (int j = 0; j < a.length; i++){

我很难阅读和理解java中的递归语句

如果我的教授向我们展示代码并问这是做什么的?它会返回什么?…我发现自己盯着代码,好像它最终会有意义…但它从来没有

例如--

public static Int mystery(int[][] a, int b) {
        int x = 0;
        for (int i = 0; i < a.length; i++){
           for (int j = 0; j < a.length; i++){
             x += (a([i][j] == b) ? 1 : 0;
        }

   }
  return x:
}
当a= {6,4,5,8},{4,6,4,8},{7,3,6,4},{1,5,7,8}


有人能解释一下吗?谢谢

大家好欢迎来到编程世界 这不是递归编程。递归是指函数调用自身时。 例如,删除文件->当有文件夹时,它会再次调用自身,并且您希望一次又一次地删除文件夹下的文件

您的示例称为“嵌套循环”->Loops of Loops,在i和j中使用的条件“a.length”是错误的

您正在尝试循环数组的数组,一个三维表格。应该是这样的

int x = 0;
for (int i = 0; i < a.length; ++i){
    for (int j = 0; j < a[i].length; ++j){
        if (a[i][j] == b) {
            ++x;
        }
}
return x;
它正在创建一个新的临时变量来保存原始的i值。 例如:


你将来会学到更多。

首先,如果你不理解某件事,不要一直盯着它,期待它突然变得有意义,因为这可能会让你感到沮丧。取而代之的是,试着把它分解成更小的部分,从你所知道的开始,一件一件地扩展

不过,说起来容易做起来难。你是怎么分的?这里有两种方法:两者都需要

低水平 一种方法是一条一条地“干运行”代码,就像你是计算机一样。这是缓慢和乏味的,但它让你最好的洞察到计算机实际上在做什么

拿一张纸,或类似的电子表格。为方法中的每个变量创建一列:a、b、x、i、j。把这个做得特别宽

该方法从设置参数开始,因此将数组写在a下,将8写在b下。接下来,x被设置为0,所以将其写在x下。然后将i设置为0,并与a.length进行比较。数组a有四个项,即内部数组,因此长度为4,当前值i,0小于该值,因此条件为true,我们进入外部循环的主体

外部循环的主体仅包含内部循环,内部循环将j设置为0,并将其与a.length进行比较。它更小,所以进入内部循环的主体

内部循环体从=,的右边开始做一些事情,首先计算出a[i]的意思。目前i是0,所以这是一个[0],它是第一个子数组。然后算出a[0][j],也就是a[0][0],也就是6。这不等于b,因此条件为false:取0并将其添加到 在x下编号,0,并在x下写入结果以替换当前值。是否将0替换为0?是的,这实际上并没有改变任何事情

现在,您已经完成了内部循环体的这个迭代,通过将i的0替换为1来执行i++,它可能应该是j++。然后再次进行测试:j仍然小于4,因此再次进行内环体测试,这次使用[1][0]

我将在这里停下来,因为这真的很乏味,但希望你能看到这个过程。内部循环继续,直到其条件变为false,然后外部循环递增i,再次启动内部循环,但这次查看a[1][0],a[1][1],依此类推。这将一直持续到外部循环也使其条件为真为止。最后,返回x的最后一个值,如果您完成所有步骤,您将得到与计算机相同的结果。试试看:一旦你掌握了窍门,它会比通读上面的内容更快,谢天谢地

好的,这给了你计算机所采取的相同的步骤序列,有时这种详细程度是非常宝贵的,特别是当你有一个错误,比如分配给错误的变量名时。但你最终可能还是不知道为什么要进行这些特殊的操作,看不见树木,看不见树木。你怎么知道这个算法的目的是什么

高层 我们看待该方法的另一种方式是计算出每一条语句的作用,以及可能的累积效应。例如,外部循环通过每个嵌套数组步进,内部循环通过嵌套数组中的每个数字步进:因此在组合中,它们通过数组a中的每个数字步进。所以所有的数字都发生了变化

此外,x在开始时设置为0,在循环中,有时添加0,有时添加1。这告诉我们这是一个计数器,最后它会告诉我们这个条件的正确性:即a中有多少个数字等于b。这就是这个方法返回的结果:b在a中出现了多少次

我们还可以告诉返回的最小值为0(当所有数字都不匹配时),最大值为数字总数,因为每个数字最多加1

这更有用:我们知道 e方法可以用于,我们可以计算出最坏的情况是什么:例如,如果我们给它超过40亿个数字,结果的32位整数就不够了;但它不会永远运行,因为数组的大小是固定的,它不会耗尽内存,因为它只为变量分配其他变量

但是您需要小心使用这种方法,因为很容易做出假设并忽略会显著改变结果的细节:例如,使用错误的比较类型或错误的变量,或者忘记清除总数,您可能最终得到的代码与您认为的不一样

当你盯着你的代码,确信它是正确的,但不知何故它仍然给你错误的答案时,这可能会导致一些最令人讨厌的错误。当这种情况发生在您身上时,切换到干运行,重新检查您的假设,或者向其他人展示您的代码:如果您不知道代码应该做什么,他们就可以发现它实际上做了什么


归根结底,这都是您将通过实践学习的技能,所以请继续编写和阅读代码。

这与递归无关。在递归中,函数调用自身直到给出退出条件。将问题分解为几个部分。你不明白哪些部分?你有第二个循环,因为int j=0;j++i is modifying i directly, making the value +1 instantly i++ means var b = i; i = b + 1;
int i = 0, j = 0;
System.out.println(i++); // will print 0, but i will be 1 moving forward
System.out.println(++j); // will print 1, and j will be 1 moving forward