在二维平面上,有一些点。请找出经过点数最多的那条线

Line findBestLine(GraphPoint[] points)

{

Line bestLine =null;

int bestCount=0;

HashMap<Double ,ArrayList<Line>> linesBySlope=

new HashMap<Double,ArrayList<Line>>();

for(int i=0;i<points.length;i++)

{

for(int j=i+1;j<points.length;j++)

{

Line line=new Line(points[i],points[j]);

insertLine(linesBySlope,line);

int count=countEquivalentLines(linesBySlope,line);

if(count>bestCount)

{

bestLine=line;

bestCount=count;

}

}

}

return bestLine;

}

int countEquivalLines(HashMap<Double,ArrayList<line>> linesBySlope,Line line)

{

double key=Line.floorToNearestEpsilon(line.slope);

double eps=Line.epsilon;

int count=countEquivalentLines(linesBySlope.get(key),line)+countEquivalentLines(linesBySlope.get(key-eps),line)+countEquivalentLines(linesBySlope.get(key+eps),line);

return count;

}

void insertLine(HashMap<Double,ArrayList<Line>> liensBySlope,Line line)

{

ArrayList<Line> lines=null;

double key=Line.floorToNearestEpsilon(line.slope);

if(!linesBySlope.containsKey(key))

{

lines=new ArrayList<Line>();

linesBySlope.put(key,lines);

}

else

{

lines=linesBySlope.get(key);

}

lines.add(line);

}

public class Line

{

public static double epsilon=.0001;

public double slope,intercept;

private boolean infinite_slope=false;

public Line(GraphPoint p,GraphPoint q)

{

if(Math.abs(p.x-q.x)>epsilon)

{

slope=(p.y-q.y)/(p.x-q.x);//斜率

intercept=p.y-slope*p.x;//利用y=mx+b计算y轴截距

}

else

{

infinite_slope=true;

intercept=p.x;//x轴截距。因为斜率无穷大

}

}

public static double floorToNearestEpsilon(double d)

{

int r=(int)(d/epsilon);

return ((double)r)*epsilon;

}

public boolean isEquivalent(double a,double b)

{

return (Math.abs(a-b)<epsilon);

}

public boolean isEquivalent(Object o)

{

Line l=(Line)o;

if(isEquivalent(l.slope,slope)&& isEquivalent(l.intercept,intercept)&&(infinitte_slope==l.infinite_slope))

{

return true;

}

return false;

}

}

计算直线的斜率务必小心谨慎,直线有可能完全垂直,也即它没有y轴截距且斜率无穷大。可用单独的标记(infinite_slope)跟踪记录。在equals方法中,必须检查这个条件。

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

时间: 2024-11-06 03:43:04

在二维平面上,有一些点。请找出经过点数最多的那条线的相关文章

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

/** * 功能:在二维平面上,有一些点,请找出经过点数最多的那条线. /** * 思路:在任意两点之间画一条无线长的直线,用散列表追踪那条直线出现的次数最多.时间复杂度O(N*N) * 注意: * 1)用斜率和y轴截距来确定是否是同一条直线. * 2)浮点数不一定能用二进制数准确表示,因此检查两个浮点数的差值是否在某个极小值(epsilon)内. * 3)对于散列表而言,斜率相等,未必散列值相同.因此,将斜率减去一个极小值,并以得到的结果flooredSlope作为散列键. * 4)取得所有可

9.7数学与概率(三)——在二维平面上,有两个正方形,请找出一条直线,能够将这两个正方形对半分

/** * 功能:在二维平面上,有两个正方形,请找出一条直线,能够将这两个正方形对半分. * 假定正方形的上下两条边与x轴平行. */ /** * 考虑: * 线的准确含义,可能性有: * 1)由斜率和y轴截距确定: * 2)由这条边上的任意两点确定: * 3)线段,以正方形的边作为起点和终点. * * 假设:这条线的端点应该落在正方形的边上. * 思路:要将两个正方形对半分,这条线必须连接两个正方形的中心点. */ public class Square { //正方形的四条边 int lef

数字之魅:寻找二维平面上的最近的点对

在二维平面上的n个点中,如何快速的找出最近的一对点,就是最近点对问题. 初看这个题,可能感觉有点儿复杂. 方案一:蛮力法.数组中总共包含N个数,所以我们可以把平面内所有的点按X轴排序,然后依次算出后一个坐标与前面所有左边的距离,然后用Min和position来记录最近的距离和两个坐标.该方案和在一维空间求两个最近点的距离有点儿类似,其时间复杂度为:O(N*N). 方案二:在一维空间里,我们知道如果数组有序,我们可以很快找出最近的两个点.我们可以用O(N*logN)的时间复杂度来对数据进行排序[快

编写一个表示二维平面上的点的类MyPoint,满足以下条件: 1、定义private的成员变量x和y,表示点的x和y坐标,类型为double

编写一个表示二维平面上的点的类MyPoint,满足以下条件:1.定义private的成员变量x和y,表示点的x和y坐标,类型为double2.定义两个MyPoint的构造方法,一个构造方法不带参数,而且x和y的初始值为0,另一个构造方法有两个参数,参数名为x和y,类型为double,用这两个参数分别作为初始x和y坐标3.定义一个getD方法,有一个类型为MyPoint的对象参数,功能为返回当前对象和参数对象这两个坐标点的距离,返回值为double类型4.编写测试的main方法,调用getD计算两

剑指Offer(Java版)第六十五题:给定一棵二叉搜索树,请找出其中的第k小的结点。 例如, (5,3,7,2,4,6,8) 中,按结点数值大小顺序第三小结点的值为4。

/*给定一棵二叉搜索树,请找出其中的第k小的结点.例如, (5,3,7,2,4,6,8) 中,按结点数值大小顺序第三小结点的值为4.*//*二叉查找树(Binary Search Tree),(又:二叉搜索树,二叉排序树)它或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值: 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值*///思路:从最左边的叶子节点开始找起. import java.util.*; public clas

C++数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。(牛客剑指offer)

///////////////////////////////////////////////////////// //数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字. //例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}. //由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2. #include <iostream> using namespace std; int Grial(int a[],int n) { if(n==0)return -1;

【转】一个数组中有三个数字a、b、c只出现一次,其他数字都出现了两次。请找出三个只出现一次的数字。

转自:http://zhedahht.blog.163.com/ 题目:一个数组中有三个数字a.b.c只出现一次,其他数字都出现了两次.请找出三个只出现一次的数字. 分析:在博客http://zhedahht.blog.163.com/blog/static/2541117420071128950682/中我们讨论了如何在一个数组中找出两个只出现一次的数字.在这道题中,如果我们能够找出一个只出现一次的数字,剩下两个只出现一次的数字就很容易找出来了. 如果我们把数组中所有数字都异或起来,那最终的结

c语言:输出一个数组,判断是否存在问题,若有,请找出问题并改正

输出一个数组,判断是否存在问题,若有,请找出问题并改正 程序: #include <stdio.h> int main() { int i, a[5] ; for (i = 0; i <=5; i++) { a[i] = 0; } for (i = 0; i <5; i++) { printf("%d\n", a[i]); } return 0; } 结果:出现崩溃 分析:循环的次数超过了数组长度 改正后程序: #include <stdio.h>

【c语言】数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字

题目:数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}, 由于数组中数字2出现了5次,超过数组的长度的一半,因此输出2 一种办法是先把数组排序,那么超过一半的元素一定是数组最中间的元素. 第二种办法比较抽象,设一个变量保存当前值,设一个次数,当前值与下一个值进行比较,如果相等,次数加一,如果不相等,次数减一,如果次数减到0了还是不相等,就把当前值替换掉.代码如下: #include <stdio.h> #includ