在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. spring 使用Spring表达式(Spring EL)

    Spring还提供了更灵活的注入方式,那就是Spring表达式,实际上Spring EL远比以上注入方式强大,我们需要学习它.Spring EL拥有很多功能. 使用Bean的id来引用Bean. •调 ...

  2. WebService学习总结(三)——使用JDK开发WebService(转)

    一.WebService的开发手段 使用Java开发WebService时可以使用以下两种开发手段 1. 使用JDK开发(1.6及以上版本) 2.使用CXF框架开发(工作中) 二.使用JDK开发Web ...

  3. 静态站点生成器-md-vue-vuepress

    推荐指数:

  4. Keil MDK仿真调试STM32的时候直接进入SystemInit函数

    1. 仿真的时候,进入之后 2. 说是main()未定义,可是明明定义了,什么原因?喔,看错了,是--main.对比了一下和正常工厂的配置,都一样,换个jlink V9测试一下吧.换了个ST LINK ...

  5. 利用eclipse导入jar包到本地仓库

    如果不也不想用mvn install xxxxxx 后面跟一大堆的东东,可以让eclipse替代完成导入,看下图 File------->Import 大功告成,可见eclipse还没有废掉,至 ...

  6. 2019年Java面试题基础系列228道(4)

    1.Java 中能创建 volatile 数组吗? 能,Java 中可以创建 volatile 类型数组,不过只是一个指向数组的引用,而不是整个数组.我的意思是,如果改变引用指向的数组,将会受到 vo ...

  7. laravel 运用.env部署多环境配置

    切换到laravel 入口文件bootstrap\app.php 在  return $app;  之上添加: $environmentPath = $app->environmentPath( ...

  8. Linux-通过源码安装某个版本的内核

    一下操作步骤来自于各种搜索出来的杂七杂八的东西.主要来自:https://blog.csdn.net/happyfreeangel/article/details/85088706 前置环境:Cent ...

  9. linux抓取top命令中数据的方法

    top在linux中是一个非常直观的命令,可以清晰地看到各进程对资源的使用情况.   但是如果你想从top命令展示中提取某些数据出来,如果想当然地使用这句命令: top|grep xxx 就会被卡住, ...

  10. SpringBoot部署到Linux上AppserverApplication,访问不到控制层

    放在本地是好好的,可以请求到,放到Linux上去的话就直接404, 解决办法: SpringBoot有个加载类叫AppserverApplication.这个大家应该都知道,我们平常都是如下写: @S ...