Exercises in this lecture   Go to the notes, in which this exercise belongs -- Keyboard shortcut: 'u'   Alphabetic index   Course home   

Exercise solution:
Documentation of class Set


Here is the class with documentation comments:

using System;
using System.Collections.Generic;
using System.Collections;

/// <summary>
///  The generic class Set with elements of type T 
/// </summary>
//  <typeparam name = "T">The type of the elements of the set </typeparam>

public class Set<T> {
 
  /* Invariant: At most one occurrence of an element in the array store 
     Consequtive storing from low end.
  */

  private int capacity;
  private static int DefaultCapacity = 3;
  private T[] store;
  private int next;

///  <summary>
///    Construct a set with an initial capacity.
///    <param name="capacity">The initial capacity of the set </param>
///  </summary>
  public Set(int capacity){
    this.capacity = capacity;
    store = new T[capacity];
    next = 0;
  }

///  <summary>
///    Construct a set with DefaultCapacity.
///  </summary>
  public Set(): this(DefaultCapacity){
  }

///  <summary>
///    Construct a set with the initial elements from elements
///    <param name="elements">An array of T elements </param>
///  </summary>
  public Set(T[] elements): this(elements.Length){
    foreach(T el in elements) this.Insert(el);
  }

  // Copy constructor

///  <summary>
///    Construct a set with initial content copied from s.
///    A copy constructor
///    <param name="s">The set of initial elements </param>
///  </summary>
  public Set(Set<T> s): this(s.capacity){
    foreach(T el in s) this.Insert(el);
  }


///  <summary> Is element member of this set.
///    <param name="element"> An element in the type T </param>
///  </summary>
  public bool Member(T element){
    for(int idx = 0; idx < next; idx++)
      if (element.Equals(store[idx]))
        return true;
    return false;
  }

///  <summary> Insert element in this set if it is not already a member.
///    <param name="element"> An element in the type T </param>
///  </summary>
  public void Insert(T element){
    if (!this.Member(element)){
      if (this.Full){
        Console.WriteLine("[Resize to {0}]", capacity * 2);
        Array.Resize<T>(ref store, capacity * 2);
        capacity = capacity * 2;
      }
      store[next] = element;
      next++;
    }
  }

///  <summary> Delete an element from the set
///    <param name="element">The element to delete </param>
///  </summary>
  public void Delete(T element){
    bool found = false;
    int  foundIdx = 0;
    for(int idx = 0; !found && (idx < next); idx++){
      if (element.Equals(store[idx])){
         found = true;
         foundIdx = idx;
      }
    }
    if (found){   // shift remaining elements left
      for(int idx = foundIdx+1; idx < next; idx++)
        store[idx-1] = store[idx];
      store[next-1] = default(T);
      next--;
    }
  }

///  <value> The number of elements in the set </value>
  public int Count{
    get{
      return next;
    }
  }

///  <summary> Is other a subset of this set.
///    <param name="other">A set of T elements </param>
///  </summary>
  // Is this set a subset of other
  public bool Subset(Set<T> other){
    foreach(T e in this)
      if (!other.Member(e))
         return false;
    return true;
  }
     
///  <summary> Return the set of elements which are both member of this set and other
///    <param name="other">A set of T elements </param>
///  </summary>
/// <seealso cref="Union(Set<T>)">
  public Set<T> Intersection(Set<T> other){
    Set<T> res = new Set<T>(this.Count);
    foreach(T e in this)
      if (other.Member(e))
          res.Insert(e);
    return res;
  }

///  <summary> Return the set of elements which are member of this or other. 
///    <param name="other">A set of T elements </param>
///  </summary>
/// <seealso cref="Intersection(Set<T>)">
  public Set<T> Union(Set<T> other){
    Set<T> res = new Set<T>(this.Count + other.Count);
    foreach(T e in this) res.Insert(e);
    foreach(T e in other) res.Insert(e);
    return res;
  }

///  <summary> Return the set of elements in this set which does not belong to other
///    <param name="other">A set of T elements </param>
///  </summary>
  public Set<T> Diff(Set<T> other){
    Set<T> res = new Set<T>(this);
    foreach(T e in other) res.Delete(e);
    return res;
  }

///  <summary> Return a string that represents this set.
///  </summary>
  public override string ToString(){
    string elRes = "";
    for(int idx = 0; idx < next; idx++) 
      if (store[idx] != null)
        elRes += " " + store[idx];
    return "{" + elRes + " "+ "}" + this.Count;
  }
  
  private class SetEnumerator: IEnumerator<T>{
 
    private readonly Set<T> set; 
    private int idx;

    public SetEnumerator (Set<T> s){
      this.set = s;
      idx = -1;   // position enumerator outside range
    }
 
    public T Current{ 
      get {
       return set.store[idx];
      }
    }

    Object IEnumerator.Current{ 
      get {
       return set.store[idx];
      }
    }

    public bool MoveNext(){
      if (idx < set.next - 1){
        idx++; 
        return true;
      }
      else
         return false;
    }

    public void Reset(){
      idx = -1;         
    }

    public void Dispose(){
    }

  }    

///  <summary> Return an enumerator of this set.
///  </summary>    
  public IEnumerator<T> GetEnumerator (){
    return new SetEnumerator(this);
  }

  private bool Full{
    get{
      return next == capacity;
    }
  }

}

The generated documentation is also available.