5種算法思想


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);
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM