I wonder is it possible to modify ternary search tree to check that word exists AND find all words that starts with that word ( or finish by that word ?) ?
For example do
=> dog
dogs
etc.
From this site is a sample code. First load all words to ternary tree then we can use method to check if word exists.
public class TernaryTree
{
private Node m_root = null;
private void Add(string s, int pos, ref Node node)
{
if (node == null) { node = new Node(s[pos], false); }
if (s[pos] < node.m_char) { Add(s, pos, ref node.m_left); }
else if (s[pos] > node.m_char) { Add(s, pos, ref node.m_right); }
else
{
if (pos + 1 == s.Length) { node.m_wordEnd = true; }
else { Add(s, pos + 1, ref node.m_center); }
}
}
public void Add(string s)
{
if (s == null || s == "") throw new ArgumentException();
Add(s, 0, ref m_root);
}
public bool Contains(string s)
{
if (s == null || s == "") throw new ArgumentException();
int pos = 0;
Node node = m_root;
while (node != null)
{
int cmp = s[pos] - node.m_char;
if (s[pos] < node.m_char) { node = node.m_left; }
else if (s[pos] > node.m_char) { node = node.m_right; }
else
{
if (++pos == s.Length) return node.m_wordEnd;
node = node.m_center;
}
}
return false;
}
}
class Node
{
internal char m_char;
internal Node m_left, m_center, m_right;
internal bool m_wordEnd;
public Node(char ch, bool wordEnd)
{
m_char = ch;
m_wordEnd = wordEnd;
}
}
This make me loome large in my mind :(
Any way to get that words could be anything. However I am weak in algorithms with that level..
I hope that I don't duplicate any questions about this.
Any suggestion I will appreciate for.
It is possible to use ternary tree for that, but I'd not recommend that (not easy to do so).
I think there are two different approaches you can use:
A., Use a standard Trie instead of a Ternary tree, so your seek time will be considered constant, no matter how many items you have in the Trie. A C# implementation is achievable, but keep in mind, Trie needs average/high level of algorithm knowledge.
B., Use a standard, sorted Array (string[]). As your requirement is just to create autocompletion based on the prefix, store all your words in a string[] and start a binary search on that. The seek time is not constant but logarithmic, but even if you have millions of words stored in that array, each seek can be measure in a fraction of a millisecond (for instance, if you have a million words in that array, only 20 operations are required to find the one you are looking for). Even if binary search was not successful, you will have an index that is a closest match (but the index will be a negative value, indicating that the match was not successful). So, in this array:
if you search for B, you will get the index 0, pointing to A. If you start stepping up, you will see the items after 'B' (or 'dog' in your example).
So, even you have a full or partial match after binary search, keep listing the items from the array until the searched keyword is at the beginning of the dictionary word.