在JAVA中求阶乘首先遇到的问题就是结果溢出,不管是使用int还是long,double都无法表示1000!这么大的天文数字,这里暂且用BigInteger解决这个问题!

  下面是使用递归和尾递归分别计算1000的阶乘:

 import java.math.BigInteger;

 public class Main {

     public static void main(String[] args) {
long t = System.currentTimeMillis();
System.out.println(factorial(new BigInteger("1000")));
System.out.println(System.currentTimeMillis()- t);
t = System.currentTimeMillis();
System.out.println(factorial2(new BigInteger("1000"),BigInteger.ONE));
System.out.println(System.currentTimeMillis()- t);
} /**
* 使用线性递归计算阶乘
* @param n
* @return
*/
public static BigInteger factorial(BigInteger n ){
if (n.compareTo(BigInteger.ZERO) < 0) return BigInteger.ZERO; if (n.equals(BigInteger.ONE) || n.equals(BigInteger.ZERO)) {
return new BigInteger("1");
}
return n.multiply(factorial(n.subtract(BigInteger.ONE)));
} /**
* 使用尾递归计算阶乘
* 如果一个函数中所有递归形式的调用都出现在函数的末尾,我们称这个递归函数是尾递归的。
* 当递归调用是整个函数体中最后执行的语句且它的返回值不属于表达式的一部分时,这个递归调用就是尾递归。
* 尾递归函数的特点是在回归过程中不用做任何操作,这个特性很重要,因为大多数现代的编译器会利用这种特点自动生成优化的代码。
* 尾递归是极其重要的,不用尾递归,函数的堆栈耗用难以估量,需要保存很多中间函数的堆栈。
* 通过参数传递结果,达到不压栈的目的
* @param n
* @param result
* @return
*/
public static BigInteger factorial2(BigInteger n,BigInteger result){
if (n.compareTo(BigInteger.ZERO) < 0) return BigInteger.ZERO; if (n.equals(BigInteger.ONE) || n.equals(BigInteger.ZERO)) {
return result;
} return factorial2(n.subtract(BigInteger.ONE),n.multiply(result));
} }

输出:

402387260077093773543702433923003985719374864210714632543799910...(太长了,省略)000
38
402387260077093773543702433923003985719374864210714632543799910...(省略)000
11
Process finished with exit code 0

  从上面的代码和运行结果可以看出,尾递归使得节省了中间函数堆栈的使用,使得性能大大提高(38-11=27毫秒)!

JAVA中使用递归和尾递归实现1000的阶乘的比较的更多相关文章

  1. Java中的递归运算

    Java中的递归运算是一种在自己的方法内部调用自己的方法 递归的设计思想是:把一个复杂的问题,分解为若干个等同的子问题,重复执行,直到之问题能够简单到直接求解,这样复杂的问题就得以解决. 递归运算有两 ...

  2. 【笔试题】Java 中如何递归显示一个目录下面的所有目录和文件?

    笔试题 Java 中如何递归显示一个目录下面的所有目录和文件? import java.io.File; public class Test { private static void showDir ...

  3. 2018.3.31 java中的递归

    java中的递归 1.概念 定义一个方法时,出现本方法调用本方法的过程,称之为递归 2.特点 必然有一个边界条件 使用递归代码往往更简洁,可读性强 3.什么时候使用递归 n的阶乘和n的累加定义 f(n ...

  4. Java中的递归调用

    Java中不合理的使用递归调用,可能会导致栈内存溢出,这点是需要注意的. java将为每个线程维护一个栈,栈里将为每个方法保存一个栈帧,栈帧代表了一个方法的运行状态. 也就是我们常说的方法栈.最后一个 ...

  5. AJPFX:不用递归巧妙求出1000的阶乘所有零和尾部零的个数

    package com.jonkey.test; import java.math.BigInteger; public class Test6 { /*** @param args*  需求:求出1 ...

  6. Java中的递归原理分析

    解释:程序调用自身的编程技巧叫做递归.        程序调用自身的编程技巧称为递归( recursion).递归做为一种算法在程序设计语言中广泛应用. 一个过程或函数在其定义或说明中有直接或间接调用 ...

  7. java基础06 Java中的递归

      一.递归是指直接或间接地调用自身. 二.递归的注意事项:             A:要有出口,否则就是死递归 B:次数不能过多,否则内存溢出 C:构造方法不能递归使用     三.举例子  递归 ...

  8. Java 中的递归

    递归 递归 一种通过调用某个方法来描述需要重复进行的操作.该方法的特点就是可以自己调用自己. 案例一 排队的问题 在生活中,我们经常需要排队.在排队中,我们怎么才能知道自己所排在第几位呢? 我们也许会 ...

  9. Java中通过递归调用删除文件夹下所有文件

    摘自 : http://blog.sina.com.cn/s/blog_79333b2c0100xiu4.html import java.io.File; public class FileTest ...

随机推荐

  1. matlab学习笔记4--MAT文件的保存和读取

    一起来学matlab-matlab学习笔记4 数据导入和导出_1 MAT文件的保存和读取 觉得有用的话,欢迎一起讨论相互学习~Follow Me 参考书籍 <matlab 程序设计与综合应用&g ...

  2. 在 ServiceModel 客户端配置部分中,找不到引用协定“WebServiceSoap”的默认终结点元素。这可能是因为未找到应用程序的配置文件,或者是因为客户端元素找不到与此协定匹配的终结点元素(转)

    按语: 在项目中实现自动升级过程,在类库中调用webservice取升级update.xml文件,添加服务调用,但在类库中调用时就出现异常,但在简单的测试工程中没有问题.解决方法采用下面介绍的方法 在 ...

  3. npm publish 一直报错 404

    在封装 zswui  react ui 组件库的时候,尝试了下 github的 packages 包设置,然后就给自己挖坑了. zswui   这是一个从零开始配置,实现组件开发测试的项目. 因为设置 ...

  4. 【Leetcode_easy】844. Backspace String Compare

    problem 844. Backspace String Compare solution1: class Solution { public: bool backspaceCompare(stri ...

  5. 04点睛Spring4.1-资源调用

    转发:https://www.iteye.com/blog/wiselyman-2210666 4.1 Resource spring用来调用外部资源数据的方式 支持调用文件或者是网址 在系统中调用p ...

  6. WebException 请求被中止: 操作超时

    HTTP 请求时出现 :WebException 请求被中止: 操作超时 处理HTTP请求的服务器 CPU 100% ,重启后正常.

  7. 网络I/O模型

    事件驱动模型 与传统编程模式不同,事件驱动程序在启动之后,就在那等待,等待什么呢?等待被事件触发.传统编程下也有“等待”的时候,比如在代码块D中,你定义了一个input(),需要用户输入数据.但这与下 ...

  8. Nginx里的root/index/alias/proxy_pass的意思

    1.[alias] 别名配置,用于访问文件系统,在匹配到location配置的URL路径后,指向[alias]配置的路径.如: location /test/ { alias /home/sftp/i ...

  9. composer 无法配置命令行写入配置文件问题

    composer config repo.packagist composer https://packagist.phpcomposer.com 这条命令无法修改composer.json 添加中国 ...

  10. 剑指offer65:矩阵中的路径(二维数组,二分查找)

    1 题目描述 请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径.路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子.如果一条路径经过了矩 ...