您的位置:首页 > 编程语言 > Java开发

Java编程算法基础----组合数学实践

2014-10-15 20:43 435 查看
《组合数学》中的许多问题都可以通过计算机给出模拟(而不是通过数学公式推出),一般是利用了计算机速度优势进行大量的枚举。许多解法中都引入“递归”算法,使得表述更加简捷。 示例:上台阶问题 n阶台阶,如果第一次上一阶台阶,则有f(n-1)种情况,第一次上二阶台阶,则有f(n-2)种情况
每个父问题都有子问题确定,递归的出口是n == 1, n == 2,此为最简单情况
代码如下:
package NO4;

public class Test25 {

	
	static int  f(int n){
		
		if(n == 1) return 1;
		if(n == 2) return 2;
		return  f(n - 1) + f(n - 2);
	}
	public static void main(String[] args) {
		// TODO Auto-generated method stub
          System.out.println(f(10));
	}

}
当n的数目较小时候,程序运行耗时还可以当n的数目较大的时候,递归会递的比较深入,耗时比较严重如f(5) ---> f(4) --->f(3) --->f(2) --->f(1) ---->f(2) ---->f(3) --->f(2) --->f(1)如上所示:递归中存在重复计算的过程,所以当n的数目较大的时候,耗时严重,此时应考虑优化
package NO4;

import java.util.*;
public class Test26 {

	static Map map = new HashMap();
	static int f(int n){
		if(map.get(n)!=null) return(Integer)map.get(n);
		int x = f(n-1) + f(n-2);
		map.put(n, x);
		return x;
	}
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
        map.put(1, 1);
        map.put(2, 2);
		System.out.println(f(45));
	}

}
以上优化做的工作是,把一个值计算完成后,即保存下来,避免重复计算利用了java中的HashMapHashMap是一种键值对的集合,表现形式为key=value,其中key是唯一的,value可以重复,如果在开发中用到需要这种表现形式的话可以用HashMap程序一直往下递,一直递到n == 1 , n == 2的情况,然后开始归,比如f(3) = f(2) + f(1),然后把f(3)的值保存起来,求f(4) = f(3) + f(2)时候,则直接调用Map存的值即可,避免重复计算f(n) f(n-1) f(n-2) f(n-3) f(n-4) f(4) f(3) f(2) f(n-5) f(2) f(1) f(n-4) f(n-3) f(n-2) f(n-3) f(n-4)f(n) f(n-1) f(n-2) f(n-3) f(4) f(3) f(2) f(1)如上所示:f(45)会一直计算f(n-1) 即 f(44) f(43) f(42)--->f(3)->f(2) f(1),然后再回调给父问题如f(3) = f(2) + f(1)f(4) = f(3) + f(2)f(5) =(f4)+f(3)示例:利用交互递归来判断一个数的奇偶性
package NO4;
//利用交互递归来实现判断一个数是否是偶数
public class Test28 {

	static boolean isEven(int n){ //判断是否是偶数
		if(n == 0)         //此为递归的出口
			return true;   
		else 
			return isOdd(n-1);   //输入一个数n,不确定它是否为偶数,则交由isOdd(n-1)判断
	}
	static boolean isOdd(int n){ //判断是否是奇数,如果他不是偶数,则返回true,若他是偶数,则返回false
		
		return !isEven(n);   //调用isEven(n)来判断,返回!isEven(n)
	}
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		//System.out.println(isEven(11));
		System.out.println(isOdd(11));
	}
}
此处空出解释的位置:交通问题如图的城市交通网,每个路口都有红绿灯。某车辆,从A点开始,打算去往B点。如果只允许车辆向上和向右行驶,那么从A到B有多少种可能的路径?代码:设A点坐标为(0,0) B点坐标为(m,n)则到达B点分两种情况,则需要首先到达点(m-1,n) 或点(m,n-1),后面一直可以继续递归边界条件为当m == 0 或者 n == 0时候,返回1
package NO4;

public class Test30 {

	static int f(int m, int n){
		
		if(m == 0) return 1;
		if(n == 0) return 1;
		return f(m-1, n) + f(m, n-1);
	}
	public static void main(String[] args) {
		// TODO Auto-generated method stub

		//System.out.println(f(1, 2));
		System.out.println(f(4, 4));
		//f(m, n);
	}

}
f(4,4)的结果为70f(2,2)的结果为6f(8,8)的结果为12870               好大呀 = =
                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: