// JavaScript Program for the above approach
// Define the Node of the tree
class Node
{
// Store the character of a string
constructor(newData)
{
this.data = newData;
// Store the end of word
this.end = 0;
// Left Subtree
this.left = null;
// Equal Subtree
this.eq = null;
// Right Subtree
this.right = null;
}
}
// Function to create a Node
function createNode(newData) {
const newNode = new Node(newData);
newNode.end = 0;
newNode.left = null;
newNode.eq = null;
newNode.right = null;
return newNode;
}
// Function to insert a word in the tree
function insert(root, word, pos = 0)
{
// Base case
if (!root) {
root = createNode(word[pos]);
}
// If the current character is less than root's data,
// then it is inserted in the left subtree
if (root.data > word[pos]) {
root.left = insert(root.left, word, pos);
}
// If current character is more than root's data,
// then it is inserted in the right subtree
else if (root.data < word[pos]) {
root.right = insert(root.right, word, pos);
}
// If current character is same as that of the root's data
else
{
// If it is the end of word
if (pos + 1 === word.length)
{
// Mark it as the end of word
root.end = 1;
}
// If it is not the end of the string, then the
// current character is inserted in the equal subtree
else {
root.eq = insert(root.eq, word, pos + 1);
}
}
return root;
}
// Function to traverse the ternary search tree
function traverse(root, ret, buff, depth = 0) {
// Base case
if (!root) {
return;
}
// The left subtree is traversed first
traverse(root.left, ret, buff, depth);
// Store the current character
buff[depth] = root.data;
// If the end of the string is detected, store it in the final ans
if (root.end) {
buff[depth + 1] = '\0';
ret.push(buff.slice(0, depth + 1).join(""));
}
// Traverse the equal subtree
traverse(root.eq, ret, buff, depth + 1);
// Traverse the right subtree
traverse(root.right, ret, buff, depth);
}
// Utility function to find all the words
function util(root, pattern)
{
// Stores the words to suggest
const buffer = Array.from({ length: 1001 }, () => null);
const ret = [];
traverse(root, ret, buffer);
if (root.end === 1) {
ret.push(pattern);
}
return ret;
}
// Function to autocomplete
// based on the given prefix
// and return the suggestions
function autocomplete(root, pattern) {
let words = [];
let pos = 0;
// If pattern is empty
// return an empty list
if (!pattern) {
return words;
}
// Iterating over the characters
// of the pattern and find it's
// corresponding node in the tree
while (root && pos < pattern.length)
{
// If current character is smaller
if (root.data > pattern[pos])
{
// Search the left subtree
root = root.left;
}
// current character is greater
else if (root.data < pattern[pos])
{
// Search right subtree
root = root.right;
}
// If current character is equal
else if (root.data === pattern[pos])
{
// Search equal subtree
// since character is found, move to
// the next character in the pattern
root = root.eq;
pos += 1;
}
// If not found
else {
return words;
}
}
// Search for all the words
// from the current node
words = util(root, pattern);
return words;
}
// Function to print
// suggested words
function printSuggestions(sugg, pat) {
for (let sug of sugg) {
console.log(pat + sug);
}
}
// Driver Code
let S = ['wallstreet', 'geeksforgeeks', 'wallmart', 'walmart', 'waldormort', 'word'];
let tree = null;
// Insert the words in the
// Ternary Search Tree
for (let str of S) {
tree = insert(tree, str);
}
let pat = 'wall';
let sugg = autocomplete(tree, pat);
if (!sugg) {
console.log('None');
} else {
printSuggestions(sugg, pat);
}
// This code is contributed by codebraxnzt