/// <summary> /// Adds word to Trei /// </summary> /// <param name="word">Word to add</param> /// <returns>true if word was added, false otherwise, returns false if word already exists</returns> internal bool AddWord(string word) { //Cannot add empty or null string if ((word?.Length ?? 0) == 0) { throw new ArgumentException("Word canot be empty or null"); } var curNode = root; var isNewWord = false; //Used to keep track of nodes traversed. We want to keep track of how //many words go through a particular node. //We will increment number of words in the end //if new word was created var traversedNodes = new List <TreiNode>(); traversedNodes.Add(root); //loop through each character in the string foreach (var c in word.ToLower()) { //Check if child node for character exists if (!curNode.Children.TryGetValue(c, out TreiNode node)) { //Add new character if it does not currently exist node = new TreiNode(c); curNode.Children[c] = node; //if a new node is created this is a new word isNewWord = true; } //traverse down to new or existing node that represents the next character. curNode = node; //Add node to list of traversed nodes traversedNodes.Add(curNode); } //Update word count for each traversed node if this is a new word. //If an existing word is added isNewWord will remain false if (isNewWord) { traversedNodes.ForEach(t => t.WordCount++); } //Mark last node as IsWord. This is required //Example: When we add word "cat" we don't want the FindWord to return //true if we search for "ca". By setting IsWord on last node only //we can determine that if we end up on node representing character "a" //from "ca" it is not a word traversedNodes[traversedNodes.Count - 1].IsWord = true; return(isNewWord); }
/// <summary> /// Create a Trei /// </summary> internal Trei() { root = new TreiNode((char)0); }