递归问题-此解决方案正确吗,有没有更简单的解决方案?

时间:2019-08-23 16:12:03

标签: java recursion

我不熟悉递归,发现以下Java问题:
编写一个获取整数n并输出数字1!,2!,3!,...,n!的函数。
这是我所做的,我想知道这是否是最简单的解决方案(我不确定,因为我使用了“ for”循环来做到这一点)。

public static void Print(int n) {
  if (n == 0) {
    System.out.print("1");
  } else {
    int temp = 1;
    for (int i = 1; i <= n, i++) {
      temp = temp * i;
    }
    Print(n-1);
    System.out.print(temp);
  }
}

顺便说一下,以前的练习是使用递归编写一个获取整数n并返回n!的函数。您是否认为我需要在这里使用它并打印它,而不是计算温度(n!)并打印它? 谢谢!

6 个答案:

答案 0 :(得分:1)

没有递归

int temp = 1;
for (int i = 1; i <= 10; ++i) {
    temp *= i;
}
System.out.println(temp);

递归就是你的循环

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

public static long print(long n) {
    if (n == 0) {
        return 1;
    }
    return n * print(n - 1);
}

输出

3628800

答案 1 :(得分:1)

您编写的内容行之有效,但是您正在重新计算一堆东西,并且当您可以递归地使用更少的代码来完成全部操作时,仍在使用for循环。

假设您无法使用函数Print(int n),则可以编写更少的代码,并且只能通过从1向上递归来计算每个阶乘并进行计算:

public static void Print(int n) {
    PrintHelper(1, n, 1);
}

private static void PrintHelper(int i, int n, long factorial) {
    if (i > n)
        return;

    factorial *= i;
    System.out.println(factorial);
    PrintHelper(i + 1, n, factorial);
}

这更易于阅读,更易于推论,并且避免一遍又一遍地进行相同的计算。

在我上面发布的示例中,我正在做n乘法。在您的示例中,由于要一次又一次地遍历每个数字(例如:1 * 2 * 3 * ... * 50,然后是1 * 2 * 3 * ... * 49,因此您正在执行n^2 / 2乘法。然后是1 * 2 * 3 * ... * 48等。

我编写的代码省略了为简化演示而进行的错误检查,因为您可以向其中添加输入完整性检查。

答案 2 :(得分:1)

这是一个简单的递归解决方案:

  public static long factorial(long n) {
    if(n == 0 || n == 1) {
      System.out.print(1 + " ");
      return 1;
    }

    long result = n * factorial(n - 1);
    System.out.print(result + " ");
    return result;
  }

答案 3 :(得分:1)

单线将看起来像:

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

ternary operator折叠if语句。然后使用递归,每个函数调用都会成为阶乘函数中的一个因素,直到达到基本情况(n <= 2):

  

4 *阶乘(3)

     
    

4 * 3 *阶乘(2)

         
      

4 * 3 * 2

    
  

答案 4 :(得分:0)

使用递归获取数字的阶乘(以前的练习),这种方法看起来像

long factorial(long n) {
    if (n > 0) {
        return n*factorial(n - 1);
    }
    return 1;
}

鉴于此,最好不要使用递归,而只需使用循环来获取数字的阶乘,就像这样:

long factorial(long n) {
    long factorial = 1;
    for (long i = 1; i <= n; i++) {
        factorial *= i;
    }
    return factorial;
}

如果要获得序列中的所有数字

long[] factorials(long n) {
    long[] factorials = new long[n+1];
    long factorial = 1;
    for (long i = 1; i <= n; i++) {
        factorial *= i;
        factorials[n] = factorial;
    }
    factorials[0] = 1;
    return factorials;
}

如果只需要打印它们,该方法将变为

void factorials(long n) {
    long factorial = 1;
    System.out.println(factorial); // 0!
    for (long i = 1; i <= n; i++) {
        factorial *= i;
        System.out.println(factorial);
    }
}

答案 5 :(得分:0)

这以不使递归表达式更难以阅读的方式增加了打印。

public class Fact {

    public static void main(String... args) {
        fact(new Long(5));
        System.out.println();
    }

    static Long fact(Long n) {
        return print(
            n == 0 || n == 1 ? 1 : n * fact(n - 1));
    }

    static Long print(Long i) {
        System.out.print(i + " ");
        return i;
    }
}