//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
// 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();
}
}
}