using System.Collections.Generic;
public static void Main()
var words = new[] { "COMPUTE", "FIVE", "CODE", "COLOR", "PUT", "EMERGENCY", "MERGE", "EMERGE" };
var trie = new Trie(words);
var input = "COMPUTEEMERGEFIVECODECOLOR";
for (var charIndex = 0; charIndex < input.Length; charIndex++)
var longestWord = FindLongestWord(trie.Root, input, charIndex);
Console.WriteLine("No word found at char index {0}", charIndex);
Console.WriteLine("Found {0} at char index {1}", longestWord, charIndex);
charIndex += longestWord.Length - 1;
static private string FindLongestWord(Trie.Node node, string input, int charIndex)
var character = char.ToUpper(input[charIndex]);
string longestWord = null;
foreach (var edge in node.Edges)
if (edge.Key.ToChar() == character)
var foundWord = edge.Value.Word;
if (!edge.Value.IsTerminal)
var longerWord = FindLongestWord(edge.Value, input, charIndex + 1);
if (longerWord != null) foundWord = longerWord;
if (foundWord != null && (longestWord == null || edge.Value.Word.Length > longestWord.Length))
public const string Chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
public static implicit operator Letter(char c)
return new Letter() { Index = Chars.IndexOf(c) };
public override string ToString()
return Chars[Index].ToString();
public bool IsTerminal { get { return Edges.Count == 0 && Word != null; } }
public Dictionary<Letter, Node> Edges = new Dictionary<Letter, Node>();
public Node Root = new Node();
public Trie(string[] words)
for (int w = 0; w < words.Length; w++)
for (int len = 1; len <= word.Length; len++)
var letter = word[len - 1];
if (!node.Edges.TryGetValue(letter, out next))
node.Edges.Add(letter, next);