using System; using System.Collections.Generic; using System.Text; namespace ScrewTurn.Wiki.SearchEngine { /// <summary> /// Implements a sorted set of integers which can be accessed by index. /// </summary> /// <remarks>Instance members are <b>not thread-safe</b>.</remarks> public class SortedBasicWordInfoSet : IEnumerable<BasicWordInfo> { private List<BasicWordInfo> items; /// <summary> /// Initializes a new instance of the <see cref="SortedBasicWordInfoSet"/> class. /// </summary> public SortedBasicWordInfoSet() : this(10) { } /// <summary> /// Initializes a new instance of the <see cref="SortedBasicWordInfoSet"/> class. /// </summary> /// <param name="capacity">The initial capacity.</param> /// <exception cref="ArgumentOutOfRangeException">If <paramref name="capacity"/> is <c>null</c>.</exception> public SortedBasicWordInfoSet(int capacity) { if(capacity <= 0) throw new ArgumentOutOfRangeException("Invalid capacity", "capacity"); items = new List<BasicWordInfo>(capacity); } /// <summary> /// Gets the count if the items in the set. /// </summary> public int Count { get { return items.Count; } } /// <summary> /// Gets the capacity of the set. /// </summary> public int Capacity { get { return items.Capacity; } } /// <summary> /// Adds a new item to the set. /// </summary> /// <param name="item">The item to add.</param> /// <returns><c>true</c> if the item is added, <c>false</c> otherwise.</returns> /// <remarks>Adding an item is <b>O(log n)</b> if the item is already in the set, /// <b>O(n)</b> otherwise, where <b>n</b> is the number of items in the set.</remarks> public bool Add(BasicWordInfo item) { int idx = items.BinarySearch(item); if(idx < 0) { // Item does not exist, insert it to the right position to avoid explicit sorting // Sort (quick sort) is O(nlogn) on average, O(n^2) worst, Insert is O(n) items.Insert(~idx, item); return true; } else return false; } /// <summary> /// Determines whether the set contains an item. /// </summary> /// <param name="item">The item to look for.</param> /// <returns><c>true</c> if the set contains the specified item, <c>false</c> otherwise.</returns> /// <remarks>The operation is <b>O(log n)</b>, where <b>n</b> is the number of items in the set.</remarks> public bool Contains(BasicWordInfo item) { if(items.Count == 0) return false; return items.BinarySearch(item) >= 0; } /// <summary> /// Removes an item from the set. /// </summary> /// <param name="item">The item to remove.</param> /// <returns><c>true</c> if the item is removed, <c>false</c> otherwise.</returns> /// <remarks>The operation is <b>O(n)</b>, where <b>n</b> is the number of items in the set.</remarks> public bool Remove(BasicWordInfo item) { if(items.Count == 0) return false; // Remove and RemoveAt are both O(n) return items.Remove(item); } /// <summary> /// Clears the set. /// </summary> /// <remarks>The operation is <b>O(1)</b>.</remarks> public void Clear() { items.Clear(); } /// <summary> /// Returns an enumerator that iterates through the set. /// </summary> /// <returns>The enumerator</returns> IEnumerator<BasicWordInfo> IEnumerable<BasicWordInfo>.GetEnumerator() { return items.GetEnumerator(); } /// <summary> /// Returns an enumerator that iterates through the set. /// </summary> /// <returns>The enumerator</returns> System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { return items.GetEnumerator(); } /// <summary> /// Gets an item from the set at a specific index. /// </summary> /// <param name="index">The zero-based index of the element to get.</param> /// <returns>The item at the specified index.</returns> /// <exception cref="IndexOutOfRangeException">If <paramref name="index"/> is outside the bounds of the collection.</exception> public BasicWordInfo this[int index] { get { if(index < 0 || index > items.Count - 1) throw new IndexOutOfRangeException("Index should be greater than or equal to zero and less than the number of items in the set"); return items[index]; } } /// <summary> /// Gets a string representation of the current instance. /// </summary> /// <returns>The string representation.</returns> public override string ToString() { StringBuilder sb = new StringBuilder(50); for(int i = 0; i < items.Count; i++) { sb.AppendFormat("{0}", items[i]); if(i != items.Count - 1) sb.Append(", "); } return sb.ToString(); } } }