首页 > 代码库 > [CC150] Find a line passing the most number of points
[CC150] Find a line passing the most number of points
Problem: Given a two-dimensional graph with points on it, find a line which passes the most number of points.
此题是Cracking the code 5th edition 第七章第六题,思路就是 n choose 2, 所以时间复杂度是O(n^2),因为没有更快的办法。
此题的难点在于两点一线计算出的斜率是浮点型,不好比较equality。所以其中需要有一个精确到哪一位的概念,英文是 round to a given place value.
我认为此题书中给的解法特别傻逼,而且时间复杂度也超出了O(n^2),故自己写了一个更好的版本。
另,关于使用自定义类用作HashMap的键值,如何重写equals()和hashCode(),下面的代码给出的很好的示范。
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 | package chapter7; import java.util.HashMap; // given a two-dimensional graph with points on it, // find a line which passes the most number of points // Time: O(N^2), N is number of points // The tricky part is checking the equality of slope // which is of type double. // My solution is floor all values to an epsilon value // which specifies the desired precision public class P6 { public Line findBestLine(GraphPoint[] points){ Line bestLine = null ; int bestCount = 0 ; HashMap<Line, Integer> lineCounts = new HashMap<Line, Integer>(); 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]); int currentCount; if (lineCounts.containsKey(line)){ currentCount = lineCounts.get(line) + 1 ; } else { currentCount = 1 ; } lineCounts.put(line, currentCount); if (currentCount > bestCount){ bestCount = currentCount; bestLine = line; } } } return bestLine; } } class Line{ // for precision // slope and intercept values are floored to epsilon public static double epsilon = . 0001 ; // properties for a normal line public double slope; public double y_intercept; // properties for a verticle line public boolean infinite_slope = false ; public double x_intercept; public Line(GraphPoint p1, GraphPoint p2){ if (p1.x == p2.x){ this .infinite_slope = true ; this .x_intercept = p1.x; } else { this .slope = (p1.y - p2.y) / (p1.x - p2.x); this .y_intercept = p1.y - slope * p1.x; } // floor all properties this .slope = floor( this .slope); this .x_intercept = floor( this .x_intercept); this .y_intercept = floor( this .y_intercept); } public double floor( double val){ int val2 = ( int )(val / epsilon); return val2 * epsilon; } @Override public int hashCode(){ if (infinite_slope){ return ( int ) x_intercept; } else { return ( int ) (slope + y_intercept); } } @Override public boolean equals(Object obj){ if ( this == obj) return true ; if (obj == null ) return false ; if (getClass() != obj.getClass()) return false ; Line other = (Line)obj; if (infinite_slope && other.infinite_slope){ // both true return x_intercept == other.x_intercept; } else if (infinite_slope || other.infinite_slope){ // one true, one false return false ; } else { // both false return slope == other.slope && y_intercept == other.y_intercept; } } } class GraphPoint{ // assume that x and y are both floored // to some point public double x; public double y; } |
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。