三種方法計算黃金分割數-java程式碼
阿新 • • 發佈:2019-02-11
最近有一好友,是個大學生,在參加學校的數學演算法大賽,內容就是黃金分割數精確到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秒的時間,
由此可見數學演算法對程式的演算法優化上是很重要的,使用合理的數學演算法,能使程式的效能大大的提升很多。