package edu.princeton.cs.algs4; import edu.princeton.cs.introcs.*; /************************************************************************* * Compilation: javac SET.java * Execution: java SET * * Set implementation using Java's TreeSet library. * Does not allow duplicates. * * % java SET * 128.112.136.11 * 208.216.181.15 * null * *************************************************************************/ import java.util.Iterator; import java.util.NoSuchElementException; import java.util.SortedSet; import java.util.TreeSet; /** * The <tt>SET</tt> class represents an ordered set of comparable keys. * It supports the usual <em>add</em>, <em>contains</em>, and <em>delete</em> * methods. It also provides ordered methods for finding the <em>minimum</em>, * <em>maximum</em>, <em>floor</em>, and <em>ceiling</em> and set methods * for <em>union</em>, <em>intersection</em>, and <em>equality</em>. * <p> * This implementation uses a balanced binary search tree. It requires that * the key type implements the <tt>Comparable</tt> interface and calls the * <tt>compareTo()</tt> and method to compare two keys. It does not call either * <tt>equals()</tt> or <tt>hashCode()</tt>. * The <em>add</em>, <em>contains</em>, <em>delete</em>, <em>minimum</em>, * <em>maximum</em>, <em>ceiling</em>, and <em>floor</em> methods take * logarithmic time in the worst case. * The <em>size</em>, and <em>is-empty</em> operations take constant time. * Construction takes constant time. * <p> * For additional documentation, see * <a href="http://algs4.cs.princeton.edu/35applications">Section 3.5</a> of * <i>Algorithms in Java, 4th Edition</i> by Robert Sedgewick and Kevin Wayne. * * @author Robert Sedgewick * @author Kevin Wayne */ public class SET<Key extends Comparable<Key>> implements Iterable<Key> { private TreeSet<Key> set; /** * Initializes an empty set. */ public SET() { set = new TreeSet<Key>(); } /** * Adds the key to the set if it is not already present. * @param key the key to add * @throws NullPointerException if <tt>key</tt> is <tt>null</tt> */ public void add(Key key) { if (key == null) throw new NullPointerException("called add() with a null key"); set.add(key); } /** * Does the set contain the given key? * @param key the key * @return <tt>true</tt> if the set contains <tt>key</tt> and * <tt>false</tt> otherwise * @throws NullPointerException if <tt>key</tt> is <tt>null</tt> */ public boolean contains(Key key) { if (key == null) throw new NullPointerException("called contains() with a null key"); return set.contains(key); } /** * Removes the key from the set if the key is present. * @param key the key * @throws NullPointerException if <tt>key</tt> is <tt>null</tt> */ public void delete(Key key) { if (key == null) throw new NullPointerException("called delete() with a null key"); set.remove(key); } /** * Returns the number of keys in the set. * @return the number of keys in the set */ public int size() { return set.size(); } /** * Is the set empty? * @return <tt>true</tt> if the set is empty, and <tt>false</tt> otherwise */ public boolean isEmpty() { return size() == 0; } /** * Returns all of the keys in the set, as an iterator. * To iterate over all of the keys in a set named <tt>set</tt>, use the * foreach notation: <tt>for (Key key : set)</tt>. * @return an iterator to all of the keys in the set */ public Iterator<Key> iterator() { return set.iterator(); } /** * Returns the largest key in the set. * @return the largest key in the set * @throws NoSuchElementException if the set is empty */ public Key max() { if (isEmpty()) throw new NoSuchElementException("called max() with empty set"); return set.last(); } /** * Returns the smallest key in the set. * @return the smallest key in the set * @throws NoSuchElementException if the set is empty */ public Key min() { if (isEmpty()) throw new NoSuchElementException("called min() with empty set"); return set.first(); } /** * Returns the smallest key in the set greater than or equal to <tt>key</tt>. * @return the smallest key in the set greater than or equal to <tt>key</tt> * @param key the key * @throws NoSuchElementException if there is no such key * @throws NullPointerException if <tt>key</tt> is <tt>null</tt> */ public Key ceiling(Key key) { if (key == null) throw new NullPointerException("called ceiling() with a null key"); Key k = set.ceiling(key); if (k == null) throw new NoSuchElementException("all keys are less than " + key); return k; } /** * Returns the largest key in the set less than or equal to <tt>key</tt>. * @return the largest key in the set table less than or equal to <tt>key</tt> * @param key the key * @throws NoSuchElementException if there is no such key * @throws NullPointerException if <tt>key</tt> is <tt>null</tt> */ public Key floor(Key key) { if (key == null) throw new NullPointerException("called floor() with a null key"); Key k = set.floor(key); if (k == null) throw new NoSuchElementException("all keys are greater than " + key); return k; } /** * Returns the union of this set and that set. * @param that the other set * @return the union of this set and that set * @throws NullPointerException if <tt>that</tt> is <tt>null</tt> */ public SET<Key> union(SET<Key> that) { if (that == null) throw new NullPointerException("called union() with a null argument"); SET<Key> c = new SET<Key>(); for (Key x : this) { c.add(x); } for (Key x : that) { c.add(x); } return c; } /** * Returns the intersection of this set and that set. * @param that the other set * @return the intersection of this set and that set * @throws NullPointerException if <tt>that</tt> is <tt>null</tt> */ public SET<Key> intersects(SET<Key> that) { if (that == null) throw new NullPointerException("called intersects() with a null argument"); SET<Key> c = new SET<Key>(); if (this.size() < that.size()) { for (Key x : this) { if (that.contains(x)) c.add(x); } } else { for (Key x : that) { if (this.contains(x)) c.add(x); } } return c; } /** * Does this set equal <tt>y</tt>? * Note that this method declares two empty sets to be equal * even if they are parameterized by different generic types. * This is consistent with the behavior of <tt>equals()</tt> * within Java's Collections framework. * @param y the other set * @return <tt>true</tt> if the two sets are equal; <tt>false</tt> otherwise */ public boolean equals(Object y) { if (y == this) return true; if (y == null) return false; if (y.getClass() != this.getClass()) return false; SET<Key> that = (SET<Key>) y; if (this.size() != that.size()) return false; try { for (Key k : this) if (!that.contains(k)) return false; } catch (ClassCastException exception) { return false; } return true; } /** * Returns a string representation of this set. * @return a string representation of this set, with the keys separated * by single spaces */ public String toString() { StringBuilder s = new StringBuilder(); for (Key key : this) s.append(key + " "); return s.toString(); } /** * Unit tests the <tt>SET</tt> data type. */ public static void main(String[] args) { SET<String> set = new SET<String>(); // insert some keys set.add("www.cs.princeton.edu"); set.add("www.cs.princeton.edu"); // overwrite old value set.add("www.princeton.edu"); set.add("www.math.princeton.edu"); set.add("www.yale.edu"); set.add("www.amazon.com"); set.add("www.simpsons.com"); set.add("www.stanford.edu"); set.add("www.google.com"); set.add("www.ibm.com"); set.add("www.apple.com"); set.add("www.slashdot.com"); set.add("www.whitehouse.gov"); set.add("www.espn.com"); set.add("www.snopes.com"); set.add("www.movies.com"); set.add("www.cnn.com"); set.add("www.iitb.ac.in"); StdOut.println(set.contains("www.cs.princeton.edu")); StdOut.println(!set.contains("www.harvardsucks.com")); StdOut.println(set.contains("www.simpsons.com")); StdOut.println(); StdOut.println("ceiling(www.simpsonr.com) = " + set.ceiling("www.simpsonr.com")); StdOut.println("ceiling(www.simpsons.com) = " + set.ceiling("www.simpsons.com")); StdOut.println("ceiling(www.simpsont.com) = " + set.ceiling("www.simpsont.com")); StdOut.println("floor(www.simpsonr.com) = " + set.floor("www.simpsonr.com")); StdOut.println("floor(www.simpsons.com) = " + set.floor("www.simpsons.com")); StdOut.println("floor(www.simpsont.com) = " + set.floor("www.simpsont.com")); StdOut.println(); // print out all keys in the set in lexicographic order for (String s : set) { StdOut.println(s); } } } /************************************************************************* * Copyright 2002-2012, Robert Sedgewick and Kevin Wayne. * * This file is part of algs4-package.jar, which accompanies the textbook * * Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne, * Addison-Wesley Professional, 2011, ISBN 0-321-57351-X. * http://algs4.cs.princeton.edu * * * algs4-package.jar is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * algs4-package.jar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with algs4-package.jar. If not, see http://www.gnu.org/licenses. *************************************************************************/