java 算法基礎

1、算法概要     
     算法是用於計算、數據處理和自動推理使用的。算法主要是做精確計算和表示一個有限長列的有效方法。算法一般包含清晰定義的指令用於計算函數。基本上也屬於一種思考最簡潔的方式。
2、算法特徵
     算法主要包含五個特徵
     2.1、有窮性;
           是指算法必須能在執行有限個步驟後終止;
     2.2、確切性;
           算法的每一個步驟必須有確切的定義;
     2.3、輸入項;
           一個算法輸入有0或多個輸入,以刻畫預算對象的初始情況,所謂0就是初始化條件;
     2.4、輸出項;
           反饋對數據加工後的結果。沒有輸出的算法無意義。
     2.5、可行性;
           算法中執行的任何計算都可以分步驟進行,每個步驟並在有限時間內完成。
3、算法常用的設計模式
      主要有十個設計模式
      3.1、完全遍歷法     
            在驗證一個問題集合時,且以驗證正確性和最優性的時候,就會採用完全遍歷法。但在便利的過程中就會消耗大量的內存。
      3.2、不完全遍歷法
             當便利時佔用的內存空間特別龐大時,可以使用不完全遍歷法來實現。例如各種規則算法和搜索算法即是。
      3.3、分治法
            把一個問題分區成互相獨立的部分,分別求解。分治法的好處在於可以並行計算。
               分治法所能解決的問題一般具有以下幾個特徵:
               (1) 該問題的規模縮小到一定的程度就可以容易地解決;
               (2) 該問題可以分解爲若干個規模較小的相同問題,即該問題具有最優子結構性質;
               (3) 利用該問題分解出的子問題的解可以合併爲該問題的解;
               (4) 該問題所分解出的各個子問題是相互獨立的,即子問題之間不包含公共的子子問題。
      3.4、動態規劃法
            當問題整體的最優解是由局部最優解組成的時候,會經常採用這種規劃方法。用於求解包含重疊子問題的最優化問題的方法。
      3.5、貪婪算法(也叫貪心算法)
            常見的近似求解思路。當問題的整體最優解不是(或無法證明是)由局部最優解組成,且對解的最優性沒有要求的時候,可以採用的一種方法。
      3.6、線性規則法
            問題是目標函數和約束條件都是線性的最優化
      3.7、簡併法
            把一個問題通過邏輯或數學推理,簡化成與之等價或者近似的、相對簡單的模型,進而求解的方法。
      3.8、窮舉法
            窮舉法,或稱爲暴力破解法,其基本思路是:對於要解決的問題,列舉出它的所有可能的情況,逐個判斷有哪些是符合問題所要求的條件,從而得到問題的解。它也常用於對於密碼的破譯。
      3.9、分枝界限法
             分枝界限法是一個用途十分廣泛的算法,運用這種算法的技巧性很強,不同類型的問題解法也各不相同。分支定界法的基本思想是對有約束條件的最優化問題的所有可行解(數目有限)空間進行搜索
      3.10、回溯法
             運用這種算法的技巧性很強,不同類型的問題解法也各不相同。分支定界法的基本思想是對有約束條件的最優化問題的所有可行解(數目有限)空間進行搜索。
6、複雜度
      6.1、時間複雜度
            時間複雜度是指着算法需要消耗的時間資源。一般來說,計算機算法說問題模型n的函數f(n),算法的時間複雜度因因此被記做
            T(N)=O(F(N))   
           算法執行時間的增長率與f(n) 的增長率正相關,稱作漸近時間複雜度(Asymptotic Time Complexity),簡稱時間複雜度。
           常見的時間複雜度有:常數階O(1),對數階O(log2n),線性階O(n), 線性對數階O(nlog2n),平方階O(n2),立方階O(n3),..., k次方階O(nk),指數階O(2n)。隨着問題規模n的不斷增大,上述時間複雜度不斷增大,算法的執行效率越低。
      6.2、空間複雜度
            算法的空間複雜度是指算法需要消耗的空間資源。其計算和表示方法與時間複雜度類似,一般都用複雜度的漸近性來表示。同時間複雜度相比,空間複雜度的分析要簡單得多。
      6.3、非確定性多項式時間複雜度(np)
            非定常多項式(英語:non-deterministic polynomial,縮寫NP)時間複雜性類,或稱非確定性多項式時間複雜性類,包含了可以在多項式時間內,對一個判定性算法問題的實例,一個給定的解是否正確的算法問題。
      6.4、複雜度特性
            所有算法都需要符合這三種特性正確性、可讀性以及健壯性。    
7、算法分類
     算法可大致分爲基本算法、數據結構的算法、數論與代數算法、計算幾何的算法、圖論的算法、動態規劃以及數值分析、加密算法、排序算法、檢索算法、隨機化算法、並行算法,厄米變形模型,隨機森林算法。
     算法可以宏泛的分爲三類:
     一,有限的,確定性算法 這類算法在有限的一段時間內終止。他們可能要花很長時間來執行指定的任務,但仍將在一定的時間內終止。這類算法得出的結果常取決於輸入值。
     二,有限的,非確定算法 這類算法在有限的時間內終止。然而,對於一個(或一些)給定的數值,算法的結果並不是唯一的或確定的。
     三,無限的算法 是那些由於沒有定義終止定義條件,或定義的條件無法由輸入的數據滿足而不終止運行的算法。通常,無限算法的產生是由於未能確定的定義終止條件。
8、幾個算法基礎小實踐

     8.1、求最大值算法

package study.arithmetic;

/**
 *求最大數值
 *我們有一串隨機數列。我們的目的是找到這個數列中最大的數。如果將數列中的每一個數字看成是一顆豆子的大小,可以將下面的算法形象地稱爲“撿豆子”:
 *首先將第一顆豆子放入口袋中。
 *從第二顆豆子開始檢查,如果正在檢查的豆子比口袋中的還大,則將它撿起放入口袋中,同時丟掉原先口袋中的豆子。反之則繼續下一顆豆子。直到最後一顆豆子。
 *最後口袋中的豆子就是所有的豆子中最大的一顆。
 */
public class Max {
	public static int max(int array[]){
	  int mval = array[0];
	  for (int i = 0; i < array.length; i++){
		  if (array[i] > mval){
		      mval = array[i];
		  }
	  }
	  return mval;
	}
}

 8.2、求最大公約數

  

package study.arithmetic;

public class Gcb {
	
	private static int gcb(int a,int b){
		if(a%b==0){
			return gcb(b,a%b);
		}
		return b;
	}
	public static void main(String args[]){
		System.out.println(gcb(110,99));
	}

}
 8.3、兔子問題

package study.arithmetic;
 /**
  * 題目:古典問題
  * 有一對兔子,從出生後第3個月起每個月都生一對兔子,小兔子長到第三個月後每個月又生一對兔子,假如兔子都不死,問每個月的兔子總數爲多少?   
  * 程序分析: 兔子的規律爲數列1,1,2,3,5,8,13,21.... 
  * @author TianYou
  */
public class CalculateRabbit {
	private static long calculateRabbit(int month){
		long rabbitOne = 1L;
		long rabbitTwo = 1L;   
		long rabbit;     
		for(int i=3; i<month; i++) {   
			rabbit = rabbitTwo;     
			rabbitTwo = rabbitOne + rabbitTwo;    
			rabbitOne = rabbit; 
		}    
		return rabbitTwo;
	}
	public static void main(String args[]){
		System.out.println(calculateRabbit(20));
	}
}

 8.4、猴子吃桃子

package study.arithmetic;

/**
 * 猴子吃桃問題:猴子第一天摘下若干個桃子,當即吃了一半,還不癮, 
 * 又多吃了一個 第二天早上又將剩下的桃子吃掉一半,又多吃了一個。 
 * 以後每天早上都吃了前一天剩下 的一半零一個。到第10天早上想再吃時,見只剩下一個桃子了。
 * 求第一天共摘了多少。
 * @author TianYou
 */
public class Monkey {
	
	private static int MonkeyPeach(int size){
		int lastdayNum = 1;    
		for(int i=2; i<=size; i++) {     
			lastdayNum = (lastdayNum+1) * 2;  
		}   
		return lastdayNum; 
	}

	public static void main(String args[]){
		System.out.println(MonkeyPeach(100));
	}
}

8.5、乒乓球比賽

package study.arithmetic;

/***
 * 兩個乒乓球隊進行比賽,各出三人。甲隊爲a,b,c三人,乙隊爲x,y,z三人。  
 * 已抽籤決定比賽名單。有人向隊員打聽比賽的名單。a說他不和x比,c說他不和x,z比,請編程序找出三隊賽手的名單。
 * @author TianYou
 */
public class EighteenthPingpang {
	private static void pingpang(char[] m,char[] n){
		for (int i = 0; i < m.length; i++) {    
			for (int j = 0; j < n.length; j++) {   
					if (m[i] == 'a' && n[j] == 'x') {       
						continue;    
					} else if (m[i] == 'a' && n[j] == 'y') { 
						continue;       
					} else if ((m[i] == 'c' && n[j] == 'x')  || (m[i] == 'c' && n[j] == 'z')) {   
						continue;     
					} else if ((m[i] == 'b' && n[j] == 'z')  || (m[i] == 'b' && n[j] == 'y')) {  
							continue;    
				    } else {    
								System.out.println(m[i] + " vs " + n[j]);    
					}    
			}
		}
	}
	public static void main(String[] args) {    
		 char[] m = { 'a', 'b', 'c' }; 
		 char[] n = { 'x', 'y', 'z' }; 
		 pingpang(m,n);
	}
}

8.6、數列求和

package study.arithmetic;

import java.text.DecimalFormat;

/**
 * 有一分數序列:2/1,3/2,5/3,8/5,13/8,21/13...求出這個數列的前20項之和
 * @author TianYou
 *
 */
public class TwentiethFractionSum {
	private static void count(){
		int x = 2, y = 1, t;   
		double sum = 0;       
		DecimalFormat df = new DecimalFormat("#0.0000");    
		 for(int i=1; i<=20; i++) {   
			   sum += (double)x / y;     
			   t = y;    
			   y = x;      
			   x = y + t;
			   System.out.println("第 " + i + " 次相加,和是 " + df.format(sum));
		 }
	}
	public static void main(String args[]){
		count();
	}

}

    8.7、2的問題

package study.arithmetic;

/**
 * 題目:求s=a+aa+aaa+aaaa+aa...a的值,其中a是一個數字。例如2+22+222+2222+22222(此時共有5個數相加),幾個數相加有鍵盤控制。 
 * 關鍵是計算出每一項的值
 * @author TianYou
 */
public class Sumloop {
	public static void main(String args[]) {
		count(5d);
	}
	private static void count(double input) {
		double s = 0;     
		double output = 0;      
		for(double i =1;i<=input;i++) {     
			output += input;      
			double a = output;      
			s+=a;     
		}      
		System.out.println(s);
	}

}

 8.8、自由落體球

package study.arithmetic;

/**
 * 題目:一球從100米高度自由落下,每次落地後反跳回原高度的一半;再落下,求它在第10次落地時,共經過多少米?第10次反彈多高? 
 * @author TianYou
 *
 */
public class Ex10 {
	public static void  count(){
		double s=0;   
		double t=100;    
		for(int i=1;i<=10;i++){     
			s+=t;          
			t=t/2; 
		}
		System.out.println(s);   
		System.out.println(t); 
	}
	public static void main(String args[]){
		count();
	}
}

 8.9、累乘

package study.arithmetic;

/**
 * 題目:求1+2!+3!+...+20!的和   
 * @author TianYou
 */
public class Ex21 {
	public static void count(){
		long sum = 0;      
		long fac = 1;       
		for(int i=1; i<=10; i++) { 
		     fac = fac * i;      
		     sum += fac;     
		 }      
		System.out.println(sum);
	}
	public static void main(String args[]){
		count();
	}
}

 8.10、遞歸求5!

package study.arithmetic;

/**
 * 遞歸公式:fn=fn_1*4! 
 * @author TianYou
 *
 */
public class Ex22 {
	public static void main(String args[]){
		recursion(5);
	}
	public static long recursion(int n) {    
		long value = 0 ;
		if(n ==1 || n == 0) {     
			value = 1;     
		} else if(n > 1) {      
			value = n * recursion(n-1);    
		}   
		return value; 
	} 

}

9、資料分享
     1、算法筆記(可以看看裏面有很多比較有意思的算法) http://www.csie.ntnu.edu.tw/~u91029/
     2、20世紀十大算法http://www.uta.edu/faculty/rcli/TopTen/topten.pdf
     3、維基算法百科:http://zh.wikipedia.org/wiki/%E7%AE%97%E6%B3%95
     4、百度算法百科:http://baike.baidu.com/link?url=5sSYcikkqGncq7qdeF3JkMKxbyFBZOLjmjqFQUP51NNhZ3zBj_xtrdMiFnkWlREX
     5、麻省理工大學算法公開課:http://v.163.com/special/opencourse/algorithms.html
     6、算法博客:http://www.iteye.com/blogs/tag/%E7%AE%97%E6%B3%95
     7、十三個經典算法研究與總結     http://blog.csdn.net/v_JULY_v/article/details/6305212
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章