基础递归方法 - 阶乘

4
我正在练习递归,但是我不明白为什么这个方法似乎不能正常工作。有什么想法吗?
    public void fact()
    {
        fact(5);
    }

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

谢谢


3
你所说的“not work”具体指什么?它做了什么?你原本期望它能做什么? - Justin Ethier
8个回答

12

你的代码似乎可以工作,但是你没有对返回值做任何处理,请将方法调用factfact(5)放在System.out.println中并查看结果。


6

递归部分是正确的;你只是没有使用它的return值,这个值被丢弃了。下面是一个完整的Java应用程序,稍微加工一下以便于教学目的:

public class Factorial {
    public static String fact(int n) {
        if(n == 1){
            return "1";
        }
        return n + " * " + (fact(n-1)); // what happens if you switch the order?
    }
    public static void main(String[] args) {
        System.out.println(fact(5));
        // prints "5 * 4 * 3 * 2 * 1"
    }
}

2
您的代码的简化版本:
public int fact(int n)
{
    if(n == 1){
        return 1;
    }
    return n * (fact(n-1));
}

可能只是:

public int fact(int n)
{
    return n == 1 ? 1 : n * fact(n - 1);
}

但是你的代码并没有错,这只是另一种风格(如果你不习惯三目运算符,请保持原样)。我更喜欢在这些情况下使用三目运算符(注意代码没有副作用)。


正如其他三位发布者在7小时前所说,算法本身没有问题。问题是原帖作者没有输出程序结果。 - Charlie Salts
但是他的代码风格很混乱。有两个出口点,一个不明确的else和不必要的括号。这就是我的观点。问题已经得到了回答。 - Jonas Fagundes
两个返回没有问题。此外,初学者可能会难以理解条件运算符的使用。 - helpermethod

1
尝试像这样做: (或者直接尝试这个)
public class factorial {

    private static int factorial( int n ){
        if (n > 1)  {
            return n * (factorial(n-1));
        } else {
            return 1;
        }
    }

    public static void main(String[] args) {
        System.out.println(factorial(100));
    }
}

1

运行良好。你没有将它分配给任何东西。这是一个测试,可以证明它的工作。

@Test
public void testYourFactorialMethod() {
    assertEquals(120, fact(5));
}

1
assertEquals()不是JUnit API的方法吗?我猜这里还没有启用JUnit,所以你可能需要更加明确一些。如果它实际上是一个常规API方法,那是我的过错。 - Pops
是的 - 这是JUnit - 我想要展示的只是他的方法是有效的。如果你读了我的评论,我并不建议他在任何地方插入我的代码。 - andyczerwonka

1
public class Recursive {

    public static void main(String[] argss) {
        System.out.print(fac(3));
    }
    public static int fac(int n) {
        int value = 0;
        if (n == 0) {
            value = 1;
        } else {
            value = n * fac(n - 1);
        }
        return value;
    }
}
// out put 6

0

-7

使用递归方法编写斐波那契数列是完全错误的!!

这是一个很久以前的著名示例,展示了好坏算法如何影响项目。

如果你用递归方式计算斐波那契数列,要计算到120需要36年才能得出结果!!!

public static int Fibonacci(int x)
{  // bad fibonacci recursive code
if (x <= 1)
      return 1;
return Fibonacci(x - 1) + Fibonacci(x - 2);
}

在.NET 4.0中,有一个新的类型名称BigInteger,您可以使用它来创建更好的函数。
使用System; using System.Collections.Generic; using System.Numerics; //需要对此程序集进行引用
namespace Fibonaci
{
 public class CFibonacci
 {
   public static int Fibonacci(int x)
   {
       if (x <= 1)
           return 1;
       return Fibonacci(x - 1) + Fibonacci(x - 2);
   }

   public static IEnumerable<BigInteger> BigFib(Int64 toNumber)
   {
       BigInteger previous = 0;
       BigInteger current = 1;

       for (Int64 y = 1; y <= toNumber; y++)
       {
           var auxiliar = current;
           current += previous;
           previous = auxiliar;
           yield return current;
       }
   }
 }
}

你可以像这样使用它

using System;
using System.Linq;

namespace Fibonaci
{
 class Program
 {
   static void Main()
   {
       foreach (var i in CFibonacci.BigFib(10))
       {
           Console.WriteLine("{0}", i);
       }

       var num = 12000;
       var fib = CFibonacci.BigFib(num).Last();
       Console.WriteLine("fib({0})={1}", num, fib);

       Console.WriteLine("Press a key...");
       Console.ReadKey();
   }
 }
}

在这种情况下,您可以在不到一秒钟的时间内计算出12000。所以

使用递归方法并不总是一个好主意

上述代码来自Vahid Nasiri博客,他用波斯语写作


3
你正在回答谁的问题? - Hendrik
6
他不是在做斐波那契数列,而是在做阶乘吧? - corsiKa
3
虽然递归可能不是编写阶乘方法的最佳方式,但它确实是介绍递归概念的简单示例。不要对提问者为什么提出问题做出假设。此外,计算出120来自于fact(5),这肯定不需要36年来处理。 - Pops
2
你的算法计算Fibonacci(n)需要 O(n) 的时间,这是令人惊讶的糟糕表现。你的评论表明,递归和迭代都不是问题所在。问题在于使用了一种糟糕的算法。 - sigfpe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接