码迷,mamicode.com
首页 > 其他好文 > 详细

9.7数学与概率(四)——在二维平面上,有一些点,请找出经过点数最多的那条线

时间:2015-08-08 15:05:13      阅读:218      评论:0      收藏:0      [点我收藏+]

标签:java   数据结构   算法   数学   

/**
 * 功能:在二维平面上,有一些点,请找出经过点数最多的那条线。
/**
	 * 思路:在任意两点之间画一条无线长的直线,用散列表追踪那条直线出现的次数最多。时间复杂度O(N*N)
	 * 注意:
	 * 		1)用斜率和y轴截距来确定是否是同一条直线。
	 * 		2)浮点数不一定能用二进制数准确表示,因此检查两个浮点数的差值是否在某个极小值(epsilon)内。
	 * 		3)对于散列表而言,斜率相等,未必散列值相同。因此,将斜率减去一个极小值,并以得到的结果flooredSlope作为散列键。
	 * 		4)取得所有可能相等的直线,搜索三个位置:flooredSlope,flooredSlope-epsilon,flooredSlope+epsilon。
	 * @param points
	 * @return
	 */
	public static MyLine1 findBestLine(GraphPoint[] points){
		MyLine1 bestLine=null;
		int bestCount=0;
		
		HashMap<Double,ArrayList<MyLine1>> lineBySlope=new HashMap<Double, ArrayList<MyLine1>>();
		
		for(int i=0;i<points.length-1;i++){
			for(int j=i+1;j<points.length;j++){
				MyLine1 line=new MyLine1(points[i],points[j]);
				insertLine(lineBySlope,line);
				int count=countEquivalentLines(lineBySlope,line);
				if(count>bestCount){
					bestCount=count;
					bestLine=line;
				}
			}
		}
		return bestLine;
		
	}

	private static int countEquivalentLines(HashMap<Double, ArrayList<MyLine1>> lineBySlope, MyLine1 line) {
		double key=line.floorToNearestEpsilon(line.slope);
		double eps=line.epsilon;
		int count=countEquivalentLines(lineBySlope.get(key), line)+countEquivalentLines(lineBySlope.get(key-eps), line)+
				countEquivalentLines(lineBySlope.get(key+eps), line);
		
		return count;
	}
	
	public static int countEquivalentLines(ArrayList<MyLine1> lines,MyLine1 line){
		if(lines==null)
			return 0;
		int count=0;
		for(MyLine1 paralleLine:lines){
			if(paralleLine==line)
				count++;
		}
		return count;
	}

	private static void insertLine(HashMap<Double, ArrayList<MyLine1>> lineBySlope, MyLine1 line) {
		ArrayList<MyLine1> lines=null;
		double key=line.floorToNearestEpsilon(line.slope);
		if(!lineBySlope.containsKey(key)){
			lines=new ArrayList<MyLine1>();
			lineBySlope.put(key, lines);
		}else{
			lines=lineBySlope.get(key);
		}
		lines.add(line);//注意此处添加的用法
	}
	
	

class MyLine1{
	public static double epsilon=0.0001;
	public double slope,intercept;
	public boolean infiniteSlope=false;
	
	public MyLine1(GraphPoint p,GraphPoint q){
		if(Math.abs(p.x-q.x)>epsilon){//两个点的x坐标不同
			slope=(p.y-q.y)/(p.x-q.x);//斜率
			intercept=p.y-slope*p.x;//y轴截距
		}else{
			infiniteSlope=true;
			intercept=p.x;//x轴截距
		}
	}
	
	public double floorToNearestEpsilon(double d){
		int r=(int) (d/epsilon);//使原d保留小数位后的4位(epsilon=0.0001)
		return ((double)r)*epsilon;
	}
	
	public boolean isEquivalent(MyLine1 line){
		if((slope==line.slope)&&(intercept==line.intercept)&&(infiniteSlope==line.infiniteSlope))
			return true;
		return false;
	}
	
	public boolean isEquivalent(double a,double b){
		return Math.abs(a-b)<epsilon;
	}
	

	
}

class GraphPoint{
	int x;
	int y;
	
	public GraphPoint(int x,int y){
		this.x=x;
		this.y=y;
	}
}

 */

版权声明:本文为博主原创文章,未经博主允许不得转载。

9.7数学与概率(四)——在二维平面上,有一些点,请找出经过点数最多的那条线

标签:java   数据结构   算法   数学   

原文地址:http://blog.csdn.net/shangqing1123/article/details/47357583

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!