1. 程式人生 > >三種方法計算黃金分割數-java程式碼

三種方法計算黃金分割數-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秒的時間,
由此可見數學演算法對程式的演算法優化上是很重要的,使用合理的數學演算法,能使程式的效能大大的提升很多。