//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\ // PLEASE DO NOT EDIT WITHOUT THE EXPLICIT CONSENT OF THE AUTHOR! \\ //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\ using System; using System.Text; using System.Collections; namespace Ilog.Language.Util { /** * A class implementing a set of objects as a hashtable. * * @version Last modified on Mon May 23 15:31:08 2005 by hak * @author Hassan Aït-Kaci * @copyright © 2000 ILOG, S.A. */ public class HashSet : IEnumerable { /** * The underlying hash table. */ private Hashtable _table; /** * Returns the number if elements in this set. */ public int Count { get { return _table.Count; } } /** * Constructs an empty HashSet. */ public HashSet () { _table = new Hashtable(); } /** * Constructs an empty HashSet with the specified capacity. */ public HashSet (int capacity) { _table = new Hashtable(capacity); } /** * Constructs a HashSet containing all the elements of the * specified collection. */ public HashSet (IList c) : this(c.Count) { foreach (Object elt in c) Add(elt); } /** * Constructs a HashSet containing all the elements of the * specified HashSet. */ public HashSet (HashSet h) : this(h.Count) { foreach (Object elt in h) Add(elt); } /** * Returns true iff this HashSet is empty. */ public bool IsEmpty { get { return _table.Count == 0; } } /** * Adds the specified element to this HashSet. */ public void Add (Object elt) { _table[elt] = elt; } /** * Removes the specified element from this HashSet. */ public void Remove (Object elt) { _table.Remove(elt); } /** * Returns true iff the specified object is an element of this HashSet. */ public bool Contains (Object elt) { return _table.ContainsKey(elt); } /** * Using this indexer on an object, one can test for containment as * it will return true or false depending on whether or not the object * belongs to this HashSet. Accordingly, assigning true or false to this * HashSet indexed by an object will add or remove it from this HashSet. */ public bool this [Object elt] { get { return Contains(elt); } set { if (value) Add(elt); else Remove(elt); } } /** * Returns true iff this HashSet is a subset of, or equal to, the * specified HashSet. */ public bool IsSubsetOf (HashSet set) { if (set.Count < _table.Count) return false; foreach (Object elt in this) if (!set.Contains(elt)) return false; return true; } /** * Returns true iff the first HashSet is a subset of, or equal to, the * second HashSet. */ public static bool IsSubsetOf (HashSet one, HashSet two) { return one.IsSubsetOf(two); } /** * Returns true iff the first HashSet is a subset of, or equal to, the * second HashSet. */ public static bool operator <= (HashSet one, HashSet two) { return one.IsSubsetOf(two); } /** * Returns true iff the first HashSet is a superset of, or equal to, the * second HashSet. */ public static bool operator >= (HashSet one, HashSet two) { return two.IsSubsetOf(one); } /** * Returns true iff this HashSet is a strict subset of the specified HashSet. */ public bool IsStrictSubsetOf (HashSet set) { return (_table.Count < set.Count) && IsSubsetOf(set); } /** * Returns true iff the first HashSet is a strict subset of the second * HashSet. */ public static bool IsStrictSubsetOf (HashSet one, HashSet two) { return one.IsStrictSubsetOf(two); } /** * Returns true iff the first HashSet is a strict subset of the second * HashSet. */ public static bool operator < (HashSet one, HashSet two) { return one.IsStrictSubsetOf(two); } /** * Returns true iff the first HashSet is a strict superset of the second * HashSet. */ public static bool operator > (HashSet one, HashSet two) { return two.IsStrictSubsetOf(one); } /** * Clears the contents of this HashSet. */ public void Clear () { _table.Clear(); } /** * Modifies and returns this set to be equal to the union of * this original HashSet and the specified one. */ public HashSet Union (HashSet set) { foreach (Object elt in set) Add(elt); return this; } /** * Returns a new HashSet equal to the union of this HashSet * and the specified one. Using this is preferred to using * the += operation since += is implemented by + and assigment, * which entails a copy of the original and thus returns a * new reference object. */ public static HashSet Union (HashSet one, HashSet two) { return new HashSet(one).Union(two); } /** * Returns a new HashSet equal to the union of this HashSet * and the specified one. */ public static HashSet operator + (HashSet one, HashSet two) { return Union(one,two); } /** * Modifies and returns this set to be equal to the intersection of this * original HashSet and the specified one. Using this is preferred to * using & the &= operation since &= is implemented by * and assigment, * which entails a copy of the original and thus returns a new reference * object. */ public HashSet Intersection (HashSet set) { ArrayList hold = new ArrayList(); foreach (Object elt in this) if (!set.Contains(elt)) hold.Add(elt); foreach (Object elt in hold) Remove(elt); return this; } /** * Returns a new HashSet equal to the intersection of this HashSet * and the specified one. */ public static HashSet Intersection (HashSet one, HashSet two) { return new HashSet(one).Intersection(two); } /** * Returns a new HashSet equal to the intersection of this HashSet * and the specified one. */ public static HashSet operator & (HashSet one, HashSet two) { return Intersection(one,two); } /** * Modifies and returns this set to be equal to the set difference * of this original HashSet and the specified one. */ public HashSet Minus (HashSet set) { foreach (Object elt in set) Remove(elt); return this; } /** * Returns a new HashSet equal to the set difference of this * HashSet and the specified one. Using this is preferred to using * the -= operation since -= is implemented by - and assigment, * which entails a copy of the original and thus returns a new * reference object. */ public static HashSet Minus (HashSet one, HashSet two) { return new HashSet(one).Minus(two); } /** * Returns a new HashSet equal to the set difference of this HashSet * and the specified one. */ public static HashSet operator - (HashSet one, HashSet two) { return Minus(one,two); } /** * Modifies and returns this set to be equal to the symmetric * difference of this original HashSet and the specified one. */ public HashSet Exclusion (HashSet set) { foreach (Object elt in set) if (Contains(elt)) Remove(elt); else Add(elt); return this; } /** * Returns a new HashSet equal to the set difference of this * HashSet and the specified one. Using this is preferred to using * the ^= operation since ^= is implemented by ^ and assigment, * which entails a copy of the original and thus returns a new * reference object. */ public static HashSet Exclusion (HashSet one, HashSet two) { return new HashSet(one).Exclusion(two); } /** * Returns a new HashSet equal to the set difference of this HashSet * and the specified one. */ public static HashSet operator ^ (HashSet one, HashSet two) { return Exclusion(one,two); } /** * Returns an enumerator for this HashSet. */ public IEnumerator GetEnumerator () { return _table.Keys.GetEnumerator(); } /** * Returns true iff the specified object is a HashSet that * contains all the elements of this HashSet. */ public override bool Equals (Object o) { if (!(o is HashSet)) return false; if (((HashSet)o).Count != _table.Count) return false; foreach (Object elt in this) if (!((HashSet)o).Contains(elt)) return false; return true; } /** * Returns a hash code for this HashSet. */ public override int GetHashCode () { int code = 0; foreach (Object elt in this) code ^= elt.GetHashCode(); return code; } /** * Returns a string representation of this HashSet. */ public override String ToString () { StringBuilder buf = new StringBuilder("{"); int count = 0; foreach (Object elt in this) { buf.Append(elt); if (++count < Count) buf.Append(", "); } return buf.Append("}").ToString(); } } }