using System; using System.Collections; using System.Collections.Generic; namespace Advanced.Algorithms.DataStructures { /// /// A suffix tree implementation using a trie. /// public class SuffixTree : IEnumerable { private Trie trie; public int Count { private set; get; } private HashSet items = new HashSet(new ArrayComparer()); public SuffixTree() { trie = new Trie(); Count = 0; } /// /// Insert a new entry to this suffix tree. /// Time complexity: O(m^2) where m is the length of entry array. /// public void Insert(T[] entry) { if (entry == null) { throw new ArgumentException(); } if (items.Contains(entry)) { throw new Exception("Item exists."); } for (var i = 0; i < entry.Length; i++) { var suffix = new T[entry.Length - i]; Array.Copy(entry, i, suffix, 0, entry.Length - i); trie.Insert(suffix); } items.Add(entry); Count++; } /// /// Deletes an existing entry from this suffix tree. /// Time complexity: O(m^2) where m is the length of entry array. /// public void Delete(T[] entry) { if (entry == null) { throw new ArgumentException(); } if (!items.Contains(entry)) { throw new Exception("Item does'nt exist."); } for (var i = 0; i < entry.Length; i++) { var suffix = new T[entry.Length - i]; Array.Copy(entry, i, suffix, 0, entry.Length - i); trie.Delete(suffix); } items.Remove(entry); Count--; } /// /// Returns true if the given entry pattern is in this suffix tree. /// Time complexity: O(e) where e is the length of the given entry. /// public bool Contains(T[] pattern) { return trie.ContainsPrefix(pattern); } /// /// Returns all sub-entries that starts with this search pattern. /// Time complexity: O(rm) where r is the number of results and m is the average length of each entry. /// public List StartsWith(T[] pattern) { return trie.StartsWith(pattern); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } public IEnumerator GetEnumerator() { return items.GetEnumerator(); } } }