/************************************************************************* * Compilation: javac Interval1D.java * Execution: java Interval1D * * 1-dimensional interval data type. * *************************************************************************/ import java.util.Arrays; import java.util.Comparator; import edu.princeton.cs.introcs.StdOut; /** * The Interval1D class represents a one-dimensional closed interval. * Intervals are immutable: their values cannot be changed after they are created. * The class Interval1D includes methods for checking whether * an interval contains a point and determining whether two intervals intersect. * * For additional documentation, see Section 1.2 of * Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne. * * @author Robert Sedgewick * @author Kevin Wayne */ public class Interval1D { /** * Compares two intervals by left endpoint. */ public static final Comparator LEFT_ENDPOINT_ORDER = new LeftComparator(); /** * Compares two intervals by right endpoint. */ public static final Comparator RIGHT_ENDPOINT_ORDER = new RightComparator(); /** * Compares two intervals by length. */ public static final Comparator LENGTH_ORDER = new LengthComparator(); private final double left; private final double right; /** * Initializes an interval [left, right]. * @param left the left endpoint * @param right the right endpoint * @throws IllegalArgumentException if the left endpoint is greater than the right endpoint * @throws IllegalArgumentException if either left or right * is Double.NaN , Double.POSITIVE_INFINITY or * Double.NEGATIVE_INFINITY */ public Interval1D(double left, double right) { if (Double.isInfinite(left) || Double.isInfinite(right)) throw new IllegalArgumentException("Endpoints must be finite"); if (Double.isNaN(left) || Double.isNaN(right)) throw new IllegalArgumentException("Endpoints cannot be NaN"); if (left <= right) { this.left = left; this.right = right; } else throw new IllegalArgumentException("Illegal interval"); } /** * Returns the left endpoint. * @return the left endpoint */ public double left() { return left; } /** * Returns the right endpoint. * @return the right endpoint */ public double right() { return right; } /** * Does this interval intersect that interval? * @param that the other interval * @return true if this interval intersects that interval; false otherwise */ public boolean intersects(Interval1D that) { if (this.right < that.left) return false; if (that.right < this.left) return false; return true; } /** * Does this interval contain the value x? * @param x the value * @return true if this interval contains the value x; false otherwise */ public boolean contains(double x) { return (left <= x) && (x <= right); } /** * Returns the length of this interval. * @return the length of this interval (right - left) */ public double length() { return right - left; } /** * Returns a string representation of this interval. * @return a string representation of this interval in the form [left, right] */ @Override public String toString() { return "[" + left + ", " + right + "]"; } // ascending order of left endpoint, breaking ties by right endpoint private static class LeftComparator implements Comparator { public int compare(Interval1D a, Interval1D b) { if (a.left < b.left) return -1; else if (a.left > b.left) return +1; else if (a.right < b.right) return -1; else if (a.right > b.right) return +1; else return 0; } } // ascending order of right endpoint, breaking ties by left endpoint private static class RightComparator implements Comparator { public int compare(Interval1D a, Interval1D b) { if (a.right < b.right) return -1; else if (a.right > b.right) return +1; else if (a.left < b.left) return -1; else if (a.left > b.left) return +1; else return 0; } } // ascending order of length private static class LengthComparator implements Comparator { public int compare(Interval1D a, Interval1D b) { double alen = a.length(); double blen = b.length(); if (alen < blen) return -1; else if (alen > blen) return +1; else return 0; } } /** * Unit tests the Interval1D data type. */ public static void main(String[] args) { Interval1D[] intervals = new Interval1D[4]; intervals[0] = new Interval1D(15.0, 33.0); intervals[1] = new Interval1D(45.0, 60.0); intervals[2] = new Interval1D(20.0, 70.0); intervals[3] = new Interval1D(46.0, 55.0); StdOut.println("Unsorted"); for (int i = 0; i < intervals.length; i++) StdOut.println(intervals[i]); StdOut.println(); StdOut.println("Sort by left endpoint"); Arrays.sort(intervals, Interval1D.LEFT_ENDPOINT_ORDER); for (int i = 0; i < intervals.length; i++) StdOut.println(intervals[i]); StdOut.println(); StdOut.println("Sort by right endpoint"); Arrays.sort(intervals, Interval1D.RIGHT_ENDPOINT_ORDER); for (int i = 0; i < intervals.length; i++) StdOut.println(intervals[i]); StdOut.println(); StdOut.println("Sort by length"); Arrays.sort(intervals, Interval1D.LENGTH_ORDER); for (int i = 0; i < intervals.length; i++) StdOut.println(intervals[i]); StdOut.println(); } }