三种方法计算黄金分割数-java代码

最近有一好友,是个大学生,在参加学校的数学算法大赛,内容就是黄金分割数精确到100位,然后我用了三种方式来算这个题:

第一种,最普通的模拟除法算题:

        Long t1=new Date().getTime();
        BigDecimal b1 = new BigDecimal(1);//初次参数分母
        BigDecimal b2 = new BigDecimal(1);//不变的分子
        List<BigDecimal> BD=new ArrayList<BigDecimal>();
        BD.add(b1);
        for(int i=0;i<10000;i++){//多次执行,使结果更精确
            //将 (1+1/1) 当作一个对象存到一个集合,每次循环都执行1+(1/上次的对象),然后将这个结果转成新的对象放到集合中
            BD.add(b2.divide(((BD.get(BD.size()-1)).divide(b2)).add(b2),110,BigDecimal.ROUND_DOWN));
        }
        System.out.println((BD.get(BD.size()-1)).setScale(100,BigDecimal.ROUND_DOWN));//设置最后的精确小数点的位数100位
        Long t2=new Date().getTime();
        System.out.println("方法一总用时:"+(t2-t1));
        System.out.println();

这种方法在我的电脑上用时在100毫秒左右,并且逻辑比较笨拙,然后根据黄金分割数的特性写出了下面一种方法。

第二种,分数合并的方式算题(使用黄金分割数公式的特性算题):

    Long ts1=new Date().getTime();
    BigDecimal cZ1 = new BigDecimal(1);//初次参数分子
    BigDecimal cM2 = new BigDecimal(2);//初次参数分母
    List<BigDecimal> BDZ=new ArrayList<BigDecimal>();//分子序列
    List<BigDecimal> BDM=new ArrayList<BigDecimal>();//分母序列
    BDZ.add(cZ1);
    BDM.add(cM2);
    for(int i=0;i<10000;i++){
        BigDecimal upCZ1,upCM1;//历史次序
        if(BDZ.size()==1){
            upCZ1=new BigDecimal(1);
            upCM1=new BigDecimal(1);
        }else{
            upCZ1=BDZ.get(BDZ.size()-2);
            upCM1=BDM.get(BDM.size()-2);
        }
        BDZ.add(upCZ1.add(BDZ.get(BDZ.size()-1)));
        BDM.add(upCM1.add(BDM.get(BDM.size()-1)));
    }
    System.out.println((BDZ.get(BDZ.size()-1)).divide((BDM.get(BDM.size()-1)),100,BigDecimal.ROUND_DOWN));
    Long ts2=new Date().getTime();
    System.out.println("用时:"+(ts2-ts1));
    System.out.println();

这种方法会比较快:用时27毫秒左右。

第三种方法,使用斐波拉契数列来算题:

        Long t3=new Date().getTime();
        BigInteger firstNum = BigInteger.ONE;//1
        BigInteger secNum = BigInteger.ONE;
        BigInteger res = BigInteger.ZERO;//0
        BigInteger TEN = BigInteger.TEN;//10
        //BigInteger的斐波那契数列
        for (int i = 0; i < 10000; i++) {
            if (i == 0 || i == 1) {
                res = BigInteger.ONE;
            }
            res = secNum.add(firstNum); //两个BigInteger相加
            firstNum = secNum;
            secNum = res;
        }
        System.out.print("0.");
        //for循环实现了模拟手算除法
        for (int i = 0; i < 101; i++) {
            //选择斐波那契里两个连续的数,小的做被除数,大的做除数
            //每一位是两者的商值
            BigInteger ans = firstNum.divide(secNum);
            //除数不变,被除数=余数*10
            firstNum = (firstNum.mod(secNum)).multiply(TEN);
            if (i!=0) {  //只输出后面的100位小数点
                System.out.print(ans);
            }
        }
        System.out.println();
        Long t4=new Date().getTime();
        System.out.println("方法三总用时:"+(t4-t3));

使用数学算法的方式计算速度更快,只用了20秒的时间,
由此可见数学算法对程序的算法优化上是很重要的,使用合理的数学算法,能使程序的性能大大的提升很多。

猜你喜欢

转载自blog.csdn.net/yuyixing101082/article/details/51801843