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

}


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