import java.util.Arrays; import java.util.Comparator; import java.util.NoSuchElementException; import java.lang.UnsupportedOperationException; import edu.princeton.cs.algs4.StdRandom; import edu.princeton.cs.algs4.StdOut; import edu.princeton.cs.algs4.Merge; import edu.princeton.cs.algs4.Quick; // "Example of Comparable and Comparator" // don't forget to rename "Point2D-solution.java" -> "Point2D.java" // "implements Comparable" means: // - the object can be compared to objects of type TTTTT // - it has a "public int compareTo(TTTTT other)" method // in its API public class Point2D implements Comparable { private final int x; // x coordinate private final int y; // y coordinate public static Comparator myYaxisComparator = new BY_Y_AXIS(); public Point2D(int x, int y) { this.x = x; this.y = y; } // compute the square of the distance between two points public static int distanceSquared(Point2D to, Point2D from) { return (to.x - from.x) * (to.x - from.x) + (to.y - from.y) * (to.y - from.y); } // implement Comparable interface // a = this b = other public int compareTo(Point2D other) { // lexicographical order // A = (x1, y1) < B = (x2, y2) // // --- if (x1 < x2) { // --- // A < B // --- return -1; // --- } else { // --- if (x1 == x2) { // --- if (y1 < y2) { // --- return -1; // --- } else if (y1 == y2) // --- // A == B (x1 == x2, y1 == y2) // --- return 0; // --- else // x1 == x2 and y1 > y2 // --- return 1; // A > B // --- } else { // x1 > x2 // --- return 1; // --- } // --- } if (this.x < other.x) return -1; else if (this.x == other.x) { return this.y - other.y; } else // this.x > other.x return 1; } public String toString() { return "(" + this.x + ", " + this.y + ")"; } // example of some (bogus) comparator public static class BY_Y_AXIS implements Comparator { public int compare(Point2D p, Point2D q) { // ... // should return NEGATIVE (or -1) if p is smaller than q // POSITIVE (or 1) if p is larger than q // ZERO if p is equal to q // ... // order according to Y-axis if (p.y < q.y) return -1; else if (p.y > q.y) return 1; else // p.y == q.y return 0; } } // Compare the distance of two points to an origin public static class byDistanceSq implements Comparator { // FIXME: add instance variable(s) private Point2D origin_of_comparator; // ================================================================ // ====> BEWARE THE CONSTRUCTOR <===== public byDistanceSq(Point2D origin) { origin_of_comparator = origin; } // ================================================================ public int compare(Point2D p, Point2D q) { // distanceSquared(Point2D to, Point2D from) int dist_p = Point2D.distanceSquared(this.origin_of_comparator, p); int dist_q = Point2D.distanceSquared(this.origin_of_comparator, q); if (dist_p < dist_q) return -1; else if (dist_p > dist_q) return 1; else return 0; } } public static void printPoints(Point2D[] a) { StdOut.print("-> "); for (int i = 0; i < a.length; i++) StdOut.print(a[i]); StdOut.println("."); } public static void main(String[] args) { // TESTING Point2D p1 = new Point2D(0, 7); Point2D p2 = new Point2D(2, 1); Point2D p3 = new Point2D(1, 0); Point2D p4 = new Point2D(0, 1); Point2D p5 = new Point2D(0, 1); Point2D p6 = new Point2D(1, 1); Point2D p7 = new Point2D(1, 3); Point2D p8 = new Point2D(10, 10); Point2D[] array = { p1, p2, p3, p4, p5, p6, p7, p8 }; printPoints(array); StdOut.println("Sorting by natural (lexicographic) order"); Arrays.sort(array); printPoints(array); StdOut.println("Sorting according to BY_Y_AXIS"); Comparator mycomparator = new BY_Y_AXIS(); // instance Arrays.sort(array, mycomparator); printPoints(array); Arrays.sort(array, Point2D.myYaxisComparator); printPoints(array); StdOut.println("Sorting according to point (9,9)"); Comparator ninenine_comparator = new byDistanceSq(new Point2D(9,9)); Arrays.sort(array, ninenine_comparator); printPoints(array); StdOut.println("Sorting according to point (1,1)"); Comparator oneone_comparator = new byDistanceSq(new Point2D(1,1)); Arrays.sort(array, oneone_comparator); printPoints(array); } // assuming arrays are sorted (duplicates are adjacent) // will count the number of distinct elements in linear time // (result is undefined if array is not sorted) public static int countDistinct(T[] elements, Comparator cmp) { // Assume elements are sorted // From Precept #1 int uniqueCount = 0; int i = 0; int N = elements.length; while (i < N) { T current = elements[i]; uniqueCount += 1; int j = i + 1; while (j < N) { // (BONUS QUESTION: how can I change this to // make an elementary check of whether the array is sorted) // element is not equal to current if (cmp.compare(elements[j], current) != 0) break; j++; } i = j; } return uniqueCount; } }