如何在表格上打印0-30的阶乘

时间:2015-04-27 22:05:52

标签: java recursion

public static void main(String[] args) {

    int n = factorial(30);
    int x = 0;
    while (x <= 30) {
        System.out.println(x + " " + n);
        x = x + 1;
    }


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

我试图打印出类似这样的内容:

0 1
1 1
2 2
3 6
4 24
...etc, up to 30 (30!)

我得到的是:

0 (30!)
1 (30!)
...etc, up to 30

总之,我能够创建从0到30的左列,但我想让它在右栏中打印数字的阶乘。使用我的代码,它只在右侧列中打印30的阶乘。我希望它按照相应的数字旁边的顺序打印阶乘。如何修复我的代码呢?

2 个答案:

答案 0 :(得分:9)

这很简单。您不必定义变量,而是每次都使用更新的x调用方法:

System.out.println(x + " " + factorial(x));

请注意,您的循环可以重写为for循环,这正是它们的设计目标:

for (int x = 0; x < 30; x++) {
    System.out.println(x + " " + factorial(x));
}

请注意以下几点:

  1. x++。它基本上是x = x + 1的简短形式,尽管有一些警告。有关详细信息,请参阅this question
  2. x在循环中定义for (int x = ...),而不是
  3. 永远不会定义或使用
  4. n。我没有设置仅使用过一次的变量,而是直接使用了factorial(x)
  5. 的结果

    注意:我确实非常确定int在面对 30!时会溢出。 265252859812191058636308480000000是一个相当大的数字。事实证明,它也会溢出long。如果要正确处理,请使用BigInteger

    public BigInteger factorial(int n) {
        if (n == 0) {
            return BigInteger.ONE;
        } else {
            return new BigInteger(n) * factorial(n - 1);
        }
    }
    

    由于BigInteger#toString()的神奇之处,您无需更改main中的任何内容即可实现此功能,但我仍然建议您遵循上述建议。

答案 1 :(得分:0)

作为@QPaysTaxes explains,您的代码中的问题是由于计算最终值然后重复打印而不是打印每一步。

然而,即使working approach缺乏效率 - 1的结果计算0和1的结果,2的结果计算0,1和2的结果,结果为3计算0,1,2和3的结果,依此类推。相反,print each step within the function itself

import java.math.BigInteger;

public class Main
{

    public static BigInteger factorial (int n) {   
        if (n == 0) {
            System.out.println("0 1");
            return BigInteger.ONE;
          } else {
            BigInteger x = BigInteger.valueOf(n).multiply(factorial(n - 1));
          System.out.println(n + " " + x);
            return x;
          }
      }
  public static void main(String[] args)
  {
    factorial(30);
  }
}

当然,仅仅multiply in the loop会更快更简单:

import java.math.BigInteger;

public class Main
{
  public static void main(String[] args)
  {
    System.out.println("0 1");
    BigInteger y = BigInteger.ONE;
    for (int x = 1; x < 30; ++x) {
        y = y.multiply(BigInteger.valueOf(x));
        System.out.println(x + " " + y);
    }
  }
}

只是为了好玩,这里是Python中有效的递归解决方案:

def f(n):
    if not n:
        print(0, 1)
        return 1
    else:
        a = n*f(n-1)
        print(n, a)
        return a

_ = f(30)

而且,更好的是,Python中的迭代解决方案:

r = 1
for i in range(31):
    r *= i or 1
    print(i, r)