在Java中使用recursion的因子

我正在使用Java:The Complete Reference这本书学习Java。 目前我正在研究主题recursion。

请注意:在stackoverflow上也有类似的问题。 我搜查了他们,但我没有find解决我的问题。 我很困惑以下程序的逻辑。

如果我运行下面的程序,它会产生正确的输出,但我不理解逻辑。

  • 我不明白以下行中的逻辑: result = fact(n-1)* n;
  • 据我所知,如果我们通过下面的程序中显示的n = 4的值,
  • 然后,3 * 4被存储在结果中,即12。
  • 再一次,事实(n-1)被调用。 然后n变成3。
  • 然后2 * 3被存储在结果中,replace前面的12。
  • 我想你明白我困惑的地方。

  • 谢谢。

class Calculation { int fact(int n) { int result; if(n==1) return 1; result = fact(n-1) * n; return result; } } public class Factorial { public static void main(String args[]) { Calculation obj_one = new Calculation(); int a = obj_one.fact(4); System.out.println("The factorial of the number is : " + a); } } 

resultfact方法的局部variables。 所以每次调用事实方法时,结果都会存储在与以前的事实调用不同的variables中。

所以当事实被调用3作为参数,你可以想象它的结果是

  result3 = fact(2) * 3 result3 = result2 * 3 result3 = 1 * 2 * 3 

首先,您应该了解factorial是如何工作的。

让我们拿4! 举个例子。

 4! = 4 * 3 * 2 * 1 = 24 

让我们使用上面的例子来模拟代码:

 int fact(int n) { int result; if(n==0 || n==1) return 1; result = fact(n-1) * n; return result; } 

在大多数编程语言中,我们称之为function stack 。 它就像一副扑克牌,每张牌都放在另一张牌的上面 – 每张牌可以被认为是一个function。所以,传递方法的fact

堆栈级别1: fact(4) // n = 4 and is not equal to 1. So we call fact(n-1)*n

堆栈级别2: fact(3)

堆叠级别3: fact(2)

堆栈级别4: fact(1) //现在,n = 1,所以我们从这个函数返回1。

返回值…

堆栈级别3: 2 * fact(1) = 2 * 1 = 2

堆栈级别2: 3 * fact(2) = 3 * 2 = 6

堆栈级别1: 4 * fact(3) = 4 * 6 = 24

所以我们得到了24。

记下这些行:

 result = fact(n-1) * n; return result; 

或者干脆:

 return fact(n-1) * n; 

这调用了函数本身。 以4为例,

按function堆栈顺序排列

 return fact(3) * 4; return fact(2) * 3 * 4 return fact(1) * 2 * 3 * 4 

代替结果…

 return 1 * 2 * 3 * 4 = return 24 

我希望你明白这一点。

我相信你的困惑来自于你认为只有一个resultvariables,而实际上每个函数调用都有一个resultvariables。 因此,旧的结果不会被replace,而是返回。

详细说明:

 int fact(int n) { int result; if(n==1) return 1; result = fact(n-1) * n; return result; } 

假设打电话给fact(2)

 int result; if ( n == 1 ) // false, go to next statement result = fact(1) * 2; // calls fact(1): | |fact(1) | int result; //different variable | if ( n == 1 ) // true | return 1; // this will return 1, ie call to fact(1) is 1 result = 1 * 2; // because fact(1) = 1 return 2; 

希望现在更清楚。

 public class Factorial { public static void main(String[] args) { System.out.println(factorial(4)); } private static long factorial(int i) { if(i<0) throw new IllegalArgumentException("x must be >= 0"); return i==0||i==1? 1:i*factorial(i-1); } } 

下面是使用recursion进行阶乘计算的另一种解释。

稍微修改源代码:

 int factorial(int n) { if (n <= 1) return 1; else return n * factorial(n - 1); } 

这里是3的计算 详情:

在这里输入图像描述

来源: RECURSION(Java,C ++)| algorithm和数据结构

会发生什么是recursion调用本身导致进一步的recursion行为。 如果你写出来,你会得到:

  fact(4) fact(3) * 4; (fact(2) * 3) * 4; ((fact(1) * 2) * 3) * 4; ((1 * 2) * 3) * 4; 

这里缺less的关键是variables“result”是一个堆栈variables,因此它不会被“replace”。 详细说明,每次调用事实时,都会在解释器内部创build一个名为“result”的NEWvariables,并链接到该方法的调用。 这与链接到对象实例的对象字段相反,而不是特定的方法调用

使用三元运算符的recursion解决scheme。

 public static int fac(int n) { return (n < 1) ? 1 : n*fac(n-1); } 

尽pipe这已经很老了,但它在谷歌中仍然保持着良好的状态。 所以我想我会提到这一点。 没有人提到检查时, x = 0

0! 和1! 都= 1。

这不是与以前的答案检查,并会导致堆栈溢出,如果事实(0)运行。 无论如何简单的修复:

 public static int fact(int x){ if (x==1 | x==0) return 1; return fact(x-1) * x; }// fact 

为了理解它,你必须以最简单的方式宣布这个方法,martynas在5月6日发表了这个方法:

 int fact(int n) { if(n==0) return 1; else return n * fact(n-1); } 

阅读上面的实现,你会明白。

不要再创build一个variables

结果

只是

return fact(n-1)* n;

 class Calculation { int fact(int n) { int result; if(n==1) return 1; return fact(n-1) * n; } } 
 import java.util.Scanner; public class Factorial { public static void main(String[] args) { Scanner keyboard = new Scanner(System.in); int n; System.out.println("Enter number: "); n = keyboard.nextInt(); int number = calculatefactorial(n); System.out.println("Factorial: " +number); } public static int calculatefactorial(int n){ int factorialnumbers=1; while(n>0){ factorialnumbers=(int)(factorialnumbers*n--); } return factorialnumbers; } } 

在我看来,这是一个有初学者水平的java知识的人的意见,我会build议n == 1改为n <= 1或(n == 0)||(n == 1)因为0的阶乘是1。

 public class Factorial2 { public static long factorial(long x) { if (x < 0) throw new IllegalArgumentException("x must be >= 0"); if (x <= 1) return 1; // Stop recursing here else return x * factorial(x-1); // Recurse by calling ourselves } } 

正确的是:

 int factorial(int n) { if(n==0||n==1) return 1; else return n*factorial(n-1); } 

这将返回1因子0.它相信我。 我已经学会了这个难题。 只是为了不保持0的条件不能清除采访。

 public class Factorial { public static void main(String[] args) { int n = 7; int result = 1; for (int i = 1; i <= n; i++) { result = result * i; } System.out.println("The factorial of 7 is " + result); } }