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