2017.01.07:面向對象設計、遞歸和動態規劃

面向對象設計

1.繼承,通過繼承方式,子類能夠改寫父類方法,同時保留部分父類方法。繼承在靜態編譯時就定義了,所以無法在運行時刻改寫父類方法。如果子類沒有改寫父類方法,就相當於依賴了父類這個方法的實現細節,會認爲破壞封裝性。如果父類接口定義需要更改時,子類也需要更改響應接口。

2.組合。對象組合通過獲得其他對象引用而在運行時刻動態定義。對象只能通過接口來訪問,所以不會破壞封裝性。使用組合方式,我們可以將類層次限制在比較小的範圍內,不容易產生類的爆炸。

3.參數化類型方式基於接口的編程,在一定程度上消除了類型給程序設計語言帶來的限制。相對於組合方式來說,缺少的是動態修改能力。

4.對象組合技術允許你在運行時刻改變被組合的行爲,但是它存在間接性,相對來說比較低效;繼承允許你提供操作的缺省實現,通過子類來重定義這些操作,但是不能夠在運行時改變;參數化允許你改變所使用的類型,同樣不能夠在運行時改變。

5.設計模式:創建型、結構型和行爲型。

創建型:創建型模式與對象的創建相關。

 單例模式:保證一個類僅僅有一個實例並且提供一個訪問它的全局訪問點。

 工廠模式:抽象類需要創建一個對象時,讓子類決定實例化哪一個類。

結構型:結構型模式處理類或者是對象的組合;

 適配器:將一個類的接口轉化爲客戶希望的另外一個接口。

行爲型:行爲型模式對類或者是對象怎樣交互和怎樣分配職責進行描述。

 觀察者:定義對象之間的依賴關係,當一個對象狀態發生改變,所有依賴這個對象的對象都會被通知並且進行更新。

 狀態:允許一個對象在其內部狀態改變時改變它的行爲。

 

遞歸和動態規劃(DP)

1.DP存儲子問題的結果,當子問題已經被計算過,直接返回結果。因此,當需要重複計算子問題時,DP的時間效率高很多,但需要額外的空間。

2.從系統層面上說,操作系統是利用函數棧來實現遞歸,每次的操作可視爲棧裏的一個對象,遞歸的時間成本隨遞歸深度n(單條路徑中遞歸調用的次數)呈指數增長,空間複雜度爲O(n)。

3.算法策略

分而治之(Divide & Conquer,D&C),將問題分成幾個部分,每一個部分相互獨立,互不重疊,假定每一個都可以得到解決來進行遞歸調用,合併每一部分的結果。

動態規劃:儘可能不重複計算每個子問題,而是將結果存儲下來,以確定後驅問題的解。

貪婪算法:只做出當下最優的判斷,並且以此爲基礎進行下一步計算。當前判斷最有時,不考慮對全局/未來的影響,所以從全局來說並不能保證總是最優。

demo1

//判斷第n個素數
int GetNthPrime(int n) {
	List<int> primes(1,2);  //init list:length 1, value 2(first prime)
	int number = 3;
	while (primes.size() != n){
		bool isPrime = true;
		for(auto it = primes.begin(); it != primes.end() && (*it)*(*it) <= number; i++){
			if (number % (*it) == 0)
				isPrime = false;
		}
		
		if (isPrime){
			primes.push_back(number);
		}
		number += 2;
	}
	return *(primes.rbegin());
}

demo2:

//假設一個機器人只能夠向下和向右移動,它從(0,0)移動到(x,y)有多少條路徑
int uniquePaths(int m, int n){
	int ways [n] = 0;
	
	ways[n-1] = 1;
	for (int i=m-1; i>=0; --i)
		for (int j=n-2; j>=0; --j)
			ways[j] += ways[j+1]
	return ways[0];
}

demo3:

//在一個整數數組中,找到最長的遞增子序列

int longestIncreasingSubsequence(int arr[], int n){
	vector<int> maxLength(n,1);
	int global_max = 0;
	for (int i=0; i<n; i++)
		for (int j=0; j<i; j++)
			if(arr[i]>arr[j] && maxLength[j]+1 > maxLength[i])
				maxLength[i] = maxLength[j]+1;
	
	for (int i=0; i<n; i++)
		if (global_max < maxLength[i])
			global_max = maxLength[i];
		
	return global_max;
}

demo4:

// eight queens
bool checkValid( int row1, int coll, int *rowCol){
	for (int row2 = row1 - 1; row2 >= 0; row2--){
		if(rowCol[row2]==coll)
			return false;
		if(abs(row1-row2) == abs(rowCol[row2]-col))
			return false'
	}
}

void placeQ(int row, int rowCol[], vector<int *> & res){
	if (row == GRID_SIZE){
		//winning
		int p[GRID_SIZE];
		for(int i=0; i<GRID_SIZE; i++)
			p[i]=rowCol[i];
		res.push_back(p);
		return;
	}
	
	int col=0;
	for (col=0; col<GRID_SIZE; col++){
		if(checkValid(row,col,rowCol)){
			rowCol[row]=col;
			placeQ(row+1, rowCol, res);
		}
	}

}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章