2011-11-18 89 views
24

我正在使用Java:The Complete Reference这本书学习Java。 目前我正在研究主题递归。在Java中使用递归的因子

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

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

  • 我不明白以下行中的逻辑:result = fact(n-1)* n;
  • 从我所知,如果我们通过n值= 4如图中下面程序,
  • 然后,将3×4被存储在结果即12
  • 再次,事实(正1)被调用。然后n变成3.
  • 然后2 * 3被存储在结果中,替换前面的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); 
    } 
} 
+1

我的建议是在深入研究Java之前,首先需要了解递归背后的数学。如果你还没有这样做,这对你来说将是一个非常好的开始en.wikipedia.org/wiki/Recursion – GETah

+1

希望这可以让你更清楚http://www.programmerinterview.com/index。PHP /递归/递归解释/ – Rangesh

回答

9

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

所以,当事实与3调用作为参数,你可以想像,其结果是

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

你的困惑,我相信,来自于一个事实,你觉得只有一个result变量,而实际上则每个函数调用result变量。因此,旧的结果不会被替换,而是返回。

阐述:

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, i.e. call to fact(1) is 1 
result = 1 * 2; // because fact(1) = 1 
return 2; 

希望它更清晰了。

+0

雅,你明白了我的观点。你能否详细说明一下。 – user907629

2

的关键点,你在这里缺少的是变量“结果”是一个堆栈变量,因此它不会被“替换”。详细说明,每次调用事实时,都会在解释器内部创建一个名为“result”的NEW变量,并链接到该方法的调用。这与链接到对象实例的对象字段相反,而不是特定的方法调用

46

首先,您应该了解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。它就像一副纸牌,其中每个卡放置在另一个之上 - ,并且每个卡可以被所以思想为函数的,传递方法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为例,

在序列根据功能栈..

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

代结果...

return 1 * 2 * 3 * 4 = return 24 

我希望你明白了吧。

+0

我认为你的意思是// n = 4并且不等于1.不知道12从哪里来。 – Gray

+0

是..编辑..谢谢.. –

+0

我的意思是,阶乘4 = 4 * 3 * 2 * 1.我的问题,起初我认为值4 * 3将被存储在结果中。 – user907629

5

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

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

虽然这是旧的,它仍然继续在谷歌很好。所以我想我会提到这一点。没有人提到检查什么时候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 
-1

不要再创建一个变量

结果

简单

回报的事实(N-1)* N;

class Calculation 
{ 
    int fact(int n) 
    { 
     int result; 

     if(n==1) 
     return 1; 

     return fact(n-1) * n; 

    } 
} 
-1
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; 
    } 
} 
0

在我看来,这是有人用java初学知识水平的意见,我建议第n == 1改变到n < = 1(N == 0)||(n == 1),因为0的阶乘是1.

-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 
    } 
} 
1

使用三元运算符的递归解决方案。

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

返回n == 1 || n == 0? 1:n * fac(n-1); – ggb667

+0

return(n <= 1)? 1:n * fact(n-1) –

0

正确的是:

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

这将返回1 0的阶乘就做相信我。我已经学会了这个难题。 只是为了保持0的条件无法清除采访。

0

要了解它,你必须声明中可能最简单的方式方法和martynas钉它在5月6日一篇:

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

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

5
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); 
    } 
} 
+1

请让我知道为什么downvote? – SanA

+1

很可能是因为你没有解释任何东西,但我喜欢你的解决方案,并且我已经投了票。 – another

10

这里又是如何阶乘计算使用递归作品的另一种解释。

让我们稍微修改源代码:

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

这里是3计算!具体为:

enter image description here

来源:RECURSION (Java, C++) | Algorithms and Data Structures

-1
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); 
} 
} 
+1

添加一些解释与答案如何帮助解决当前问题 –

-1

那么这里是一个使用递归发现一些阶乘的逻辑,

static int factorialFunction(int n) 
{ 
    int result; 
    if(n == 1) 
    { 
     return 1; 
    } 
    // here we are calling the recursion function 
    result = factorialFunction(n - 1) * n; 
    return result; 
} 

同时你可以参考this资源使用递归找到一个数的阶乘例子。