java实现50000的阶乘

来源:互联网 发布:php会员管理系统模板 编辑:程序博客网 时间:2024/06/05 16:34
前几天在群共享里看到一个人上传的“50000!.txt”当时觉得比较好奇就下下来了,双击打开看了下,晕,这么大个家伙,光打开就占用了好几秒的时间,也在当时明白了这个文档的特殊性了,今天心血来潮,也想试着自己写下50000的阶乘,最开始我是用递归实现的,代码如下:
    /**
     * 递归实现求阶乘
     * @param n
     * @return
     */
    public static BigInteger getResult(long n) {
        if (n==1) {
            return BigInteger.valueOf(1);
        }
        else {
            return getResult(n-1).multiply(BigInteger.valueOf(n-1));
        }
    }
写好后随便输了个数(10,20)试了下,没问题,后来试了下5000,也没问题,再改成10000,结果就报错了,java.lang.StackOverflowError,堆栈溢出!网上查了下,原来是递归的层次太多了,看来递归也不是什么特别特别号的方法哈,当然他也有他自己的好处,那不行啊,得改成循环,就又写了个循环的方法:
    /**
     * 循环实现求n的阶乘
     * @param n
     * @return
     */
    public static BigInteger xunHuan(long n) {
        BigInteger cBigInteger=BigInteger.valueOf(1);
        for (long i =1; i < n+1; i++) {
            cBigInteger=cBigInteger.multiply(BigInteger.valueOf(i));
        }
        return cBigInteger;
    }
嗯,这个求10000的阶乘是没问题了,但是还是有问题啊,50000这数字太大了,算起来要好长时间的,40多秒,就又想了个办法,把它分成两次计算,然后这两部分相乘,
    public static BigInteger getAnothor(long begin,long end) {
        BigInteger cBigInteger=BigInteger.valueOf(1);
        for (long i = begin; i < end; i++) {
            cBigInteger=cBigInteger.multiply(BigInteger.valueOf(i));
        }
        return cBigInteger;
    }
试了下,效率是要比刚才那个高些,但是我在想,能不能用线程来实现计算呢,启动不同的线程计算不同的部分,最后把结果相乘,这样效率是不是会更高点呢?先就写到这里,我先试下,能实现了再放上去