package BaseAlgo; import java.util.Scanner; /* * 遞歸算法:不斷反復調用自身來解決問題。要求問題能夠分解為相同問題的一個子問題。 * 直接遞歸:調用本身 * 間接遞歸:a 調用b b 再調用a;(用的不多) * 遞歸前一般有一個if語句作為遞歸出口,否則無限調用自身,引發堆棧溢出。 * * 實例:階乘問題 */ public class Digui { public static int fact(int n){ if(n<=1){ return 1;//出口 }else{ return n* fact(n-1); } } public static void main(String[] args) { System.out.println("輸入要求階乘的一個整數:"); Scanner input = new Scanner(System.in); int n = input.nextInt(); System.out.println("階乘的結果為:" + fact(n)); } }
package BaseAlgo; import java.util.Scanner; /* * 遞推算法:根據已有的數據和關系,逐步推導而得到結果。常用於數學場合,能夠抽象出數學公式 * 1.根據已知結果和關系(明確邏輯關系),求中間結果。 * 2. 判斷是否達到要求,如果沒達到,則繼續求,如果滿足要求,則表示尋找到一個正確答案 * * 實例:一對兩個月大的兔子以后每一個月都可以生一對小兔子,而新生兔子要出生兩個月后才能生小兔子。如1月出生, * 3月才能產仔。問一年后有幾對兔子? * 規律:每月兔子總數等於前兩個月的兔子數之和。 */ public class ditui { public static int fibonacci(int n){ int t1, t2; if(n == 1 || n==2){ return 1; }else{ t1 = fibonacci(n-1); t2 = fibonacci(n-2);//遞歸 return t1 + t2 ; } } public static void main(String[] args) { System.out.println("遞推算法求兔子產仔問題!"); System.out.println("輸入時間月數:"); Scanner input = new Scanner(System.in); int n = input.nextInt(); int num = fibonacci(n); System.out.println("一對兔子經過" + n +"個月的繁殖后" + "共有" + num + "對兔子!" ); } }
package BaseAlgo; import java.util.Scanner; /* * 窮舉算法 Exhaustive Attack method * 依賴計算機強大的計算能力,來窮盡每一種可能的情況。選出符合要求的結果。 * 執行步驟:1.對於一種可能的情況,計算其結果。2,判斷結果是否滿足需求,如不滿足進行第一步。 * * 實例:雞兔同籠問題:上有三十五頭,下有九十四足,問兔雞各幾何? */ public class ExhaustiveAttackmethod { static int chichen,rabbit; public static int qiongju(int foot, int head){ int re ,j ,i; re=0; for(i=0;i<=head;i++){ j=head-i; if(i*4+j*2 == foot){ re=1; chichen = j; rabbit = i; } } return re; } public static void main(String[] args) { int re , foot,head; System.out.println("用窮舉算法計算雞兔同籠問題:"); Scanner input = new Scanner(System.in); System.out.println("請輸入頭數:"); head = input.nextInt(); System.out.println("請輸入腳數:"); foot = input.nextInt(); re = qiongju(foot,head); if(re==1){ System.out.println("雞有" + chichen + "只," + "兔有" + rabbit +"只。"); }else{ System.out.println("無解!"); } } }
package BaseAlgo; import java.util.Scanner; /* * 分治算法:將一個計算復雜的問題分為規模小,計算簡單的小問題來求解。然后再綜合各個小問題,而得到最終的答案。 * 執行過程: * 1.對於一個規模為N的問題,若該問題可以容易地解決,則直接解決,否則執行以下步驟。 * 2.分解問題為M個規模的子問題,這些子問題是相互獨立的,並且與原問題形式相同。 * 3.遞歸地解決這些子問題 * 4.然后,將子問題的解合並得到原問題的解。 * * 實例:有30個硬幣,其中有一枚是假幣,知假幣比真幣輕,問如何找到假幣? * * 分析:將硬幣均分為兩堆,放到天平上去稱,較輕的一堆包含假幣,重復上述操作, * 直到剩下兩枚時,就可以直接用天平找出假幣。 * */ public class Fenzhi { static final int MAXNUM = 30; static int FindFalseCoin(int coin[], int low ,int high){ int i ,sum1,sum2,sum3; int re = 0; sum1=sum2=sum3=0; //兩枚硬幣時 if(low+1 == high){ if(coin[low]<coin[high]){ re = low + 1;//數組初始下標為0 ,需加一 return re; }else{ re = high+1; return re; } } //大於2且為偶數時 if((high - low +1)%2 == 0){ for(i=low;i<=low+(high-low)/2;i++){ sum1 = sum1 + coin[i];//總重量 } for(i= low + (high-low)/2+1; i<=high;i++){ sum2 = sum2 + coin[i];//另一對待的總重量 } if(sum1<sum2){ re = FindFalseCoin(coin, low, low+(high-low)/2); return re; }else if(sum1>sum2){ re = FindFalseCoin(coin, low+(high-low)/2+1, high); return re; }else{ } } //奇數 else{ for(i=low;i<=low+(high-low)/2-1;i++){ sum1 = sum1 +coin[i]; } for(i=low+(high-low)/2+1;i<=high;i++){ sum2 = sum2 + coin[i]; } sum3=coin[low+(high-low)/2];//中間數 if(sum1>sum2){ re = FindFalseCoin(coin, low+(high-low)/2+1, high); return re; }else if(sum1<sum2){ re = FindFalseCoin(coin, low, low+(high-low)/2-1); return re; }else{ } if(sum2+sum3 == sum1+sum3) { re = low+(high-low)/2+1; return re; } } return re; } public static void main(String[] args) { int[] coin = new int[MAXNUM]; int i,n,posion; System.out.println("分治算法求解假硬幣問題!"); System.out.println("請輸入硬幣總個數:"); Scanner input = new Scanner(System.in); n =input.nextInt(); System.out.println("輸入各個硬幣的總量:"); for(i=0;i<n;i++){ coin[i] = input.nextInt(); } posion= FindFalseCoin(coin, 0, n-1); System.out.println("在上述" + n + "個硬幣中,第" + posion + "個是假硬幣!" ); } }
package BaseAlgo; import java.util.Scanner; /* * 概率算法:用概率統計思路來解決問題,不能得到問題的實際接,但可得到近似值。 * 基本步驟: * 1.將問題轉化為相應的幾何圖形S,S的面積是容易計算的,為題的結果往往對應幾何圖形中的某一部分S1的面積。 * 2.然后,向幾何圖形隨機撒點。 * 3.統計幾何圖形S中和S1中的點數。根據S面積和S1面積的關系以及各圖形中的點數來計算得到結果。 * 4.判斷上述結果是否在需要的精度之內,如果未達到精度則再進行步驟二。 * * 數值概率算法:蒙特卡羅(Monte Carlo)、拉斯維加斯(Las Vegas)、舍伍德(Sherwood)。 * * Monte Carlo實例:計算圓周率π。 */ public class Gailv { static double MontePI(int n ){ double PI; double x,y; int i,sum; sum = 0; for(i=1;i<n;i++){ x= Math.random(); y=Math.random(); if(x*x + y*y <= 1 ){ sum++; } } PI=4.0*sum/n; return PI; } public static void main(String[] args) { int n; double PI; System.out.println("蒙特卡羅概率算法計算π:"); Scanner input = new Scanner(System.in); System.out.println("輸入點的數量:"); n = input.nextInt(); PI = MontePI(n); System.out.println("π=" + PI); } }
