Point是一个具有两个实例变量的类,它们是一个点的坐标。 (X,Y) Point实现Comparable接口。但除了通过它们的坐标进行比较之外,任何点(x1,y1)也可以与它们相对于另一个点(x0,y0)的相对斜率(x2,y2)进行比较。以下是Point类:
import java.util.Comparator;
public class Point implements Comparable<Point> {
// compare points by slope
public final Comparator<Point> SLOPE_ORDER = new Ordering();
private final int x; // x coordinate
private final int y; // y coordinate
// create the point (x, y)
public Point(int x, int y) {
/* DO NOT MODIFY */
this.x = x;
this.y = y;
}
private class Ordering implements Comparator<Point>{
@Override
public int compare(Point p1, Point p2) {
if(slopeTo(p1) - slopeTo(p2) < 0) return -1;
else if(slopeTo(p1) - slopeTo(p2) > 0) return 1;
else return 0;
}
}
// slope between this point and that point
public double slopeTo(Point that) {
/* YOUR CODE HERE */
if(this.y == that.y && this.x == that.x) return Double.NEGATIVE_INFINITY;
else if(this.y == that.y) return 0;
else if(this.x == that.x) return Double.POSITIVE_INFINITY;
else return ((double)that.y - (double)this.y)/((double)that.x - (double)this.x);
}
// is this point lexicographically smaller than that one?
// comparing y-coordinates and breaking ties by x-coordinates
public int compareTo(Point that) {
/* YOUR CODE HERE */
if(this.y < that.y){
return -1;
}else if(this.y > that.y){
return 1;
}else{
if(this.x < that.x) return -1;
else if(this.x > that.x) return 1;
else return 0;
}
}
}
现在我写了一个简单的测试类来测试斜率排序是否有效。
public class Test {
public static void main(String[] args) {
In in = new In(args[0]);
int N = in.readInt();
Point[] points = new Point[N];
Point[] pointsBySlope = new Point[N];
for (int i = 0; i < N; i++) {
int x = in.readInt();
int y = in.readInt();
points[i] = new Point(x, y);
pointsBySlope[i] = points[i];
}
Arrays.sort(points);
Arrays.sort(pointsBySlope);
Point p = points[2];
Arrays.sort(pointsBySlope, p.SLOPE_ORDER);
p = points[3];
Arrays.sort(pointsBySlope, p.SLOPE_ORDER);
for(int i=0;i<pointsBySlope.length;i++){
System.out.println(pointsBySlope[i].toString()+" , ");
}
System.out.println("\n\n"+"=================================");
Arrays.sort(pointsBySlope);
Arrays.sort(pointsBySlope, p.SLOPE_ORDER);
for(int i=0;i<pointsBySlope.length;i++){
System.out.println(pointsBySlope[i].toString()+" , ");
}
}
}
输出
(19000, 10000) ,
(18000, 10000) ,
(14000, 10000) ,
(21000, 10000) ,
(32000, 10000) ,
(1234, 5678) ,
(19000, 10000) ,
(14000, 10000) ,
(18000, 10000) ,
(21000, 10000) ,
(32000, 10000) ,
(1234, 5678) ,
为什么两种情况下的输出都不同?最初如何按自然顺序对pointsBySlope数组进行排序,然后通过SLOPE_ORDER进行排序,直接按SLOPE_ORDER排序会产生不同的输出?
答案 0 :(得分:1)
在两种排序中,p
为(19000, 10000)
。然后,(14000, 10000), (18000, 10000), (21000, 10000), (32000, 10000)
中的每一个都有p
的“0
的斜率”。这意味着您的比较器不会重新排序这些点;它会在排序之前以任何顺序离开它们。对于你的第二个输出,这恰好是点的自然顺序;对于第一个输出,它不是。