How to implement text Auto-complete feature using Ternary Search Tree - GeeksforGeeks

05 Aug, 2021
Given a set of strings S and a string patt the task is to autocomplete the string patt to strings from S that have patt as a prefix, using a Ternary Search Tree. If no string matches the given prefix, print “None”.Examples:  
Input: S = {“wallstreet”, “geeksforgeeks”, “wallmart”, “walmart”, “waldomort”, “word”], patt = “wall” Output: wallstreet wallmart Explanation: Only two strings {“wallstreet”, “wallmart”} from S matches with the given pattern “wall”.Input: S = {“word”, “wallstreet”, “wall”, “wallmart”, “walmart”, “waldo”, “won”}, patt = “geeks” Output: None Explanation: Since none of word of set matches with pattern so empty list will be printed.  
 
Trie Approach: Please refer this article to learn about the implementation using Trie data structure.Ternary Search Tree Approach Follow the steps below to solve the problem:  
Insert all the characters of the strings in S into the Ternary Search Tree based on the following conditions: If the character to be inserted is smaller than current node value, traverse the left subtree.If the character to be inserted is greater than current node value, traverse the right subtree to.If the character to be inserted is same as that of the current node value, traverse the equal subtree if it is not the end of the word. If so, mark the node as the end of the word.
If the character to be inserted is smaller than current node value, traverse the left subtree.If the character to be inserted is greater than current node value, traverse the right subtree to.If the character to be inserted is same as that of the current node value, traverse the equal subtree if it is not the end of the word. If so, mark the node as the end of the word.
If the character to be inserted is smaller than current node value, traverse the left subtree.
If the character to be inserted is greater than current node value, traverse the right subtree to.
If the character to be inserted is same as that of the current node value, traverse the equal subtree if it is not the end of the word. If so, mark the node as the end of the word.
Follow a similar approach for extracting suggestions.
Traverse the tree to search the given prefix patt following a similar traversal technique as mentioned above.
If the given prefix is not found, print “None”.
If the given prefix is found, traverse the tree from the node where the prefix ends. Traverse the left subtree and generate suggestions followed by the right and equal subtrees from every node .
Every time a node is encountered which has the endofWord variable set, it denotes that a suggestion has been obtained. Insert that suggestion into words.
Return words after generating all possible suggestions.
Below is the implementation of the above approach:  
C++
// C++ Program to generate// autocompleted texts from// a given prefix using a// Ternary Search Tree#include <bits/stdc++.h>using namespace std; // Define the Node of the// treestruct Node {     // Store the character    // of a string    char data;    // Store the end of    // word    int end;    // Left Subtree    struct Node* left;     // Equal Subtree    struct Node* eq;     // Right Subtree    struct Node* right;}; // Function to create a NodeNode* createNode(char newData){    struct Node* newNode = new Node();    newNode->data = newData;    newNode->end = 0;    newNode->left = NULL;    newNode->eq = NULL;    newNode->right = NULL;    return newNode;} // Function to insert a word// in the treevoid insert(Node** root,            string word,            int 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])        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])        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.size())            // 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            insert(&((*root)->eq), word, pos + 1);    }} // Function to traverse the ternary search treevoid traverse(Node* root,              vector<string>& ret,              char* buff,              int 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_back(string(buff));    }     // 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 wordsvector<string> util(Node* root,                    string pattern){    // Stores the words    // to suggest    char buffer[1001];     vector<string> ret;     traverse(root, ret, buffer);     if (root->end == 1)        ret.push_back(pattern);    return ret;} // Function to autocomplete// based on the given prefix// and return the suggestionsvector<string> autocomplete(Node* root,                            string pattern){    vector<string> words;    int pos = 0;     // If pattern is empty    // return an empty list    if (pattern.empty())        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++;        }         // 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 void print(vector<string> sugg,           string pat){    for (int i = 0; i < sugg.size();         i++)        cout << pat << sugg[i].c_str()             << "\n";} // Driver Codeint main(){    vector<string> S        = { "wallstreet", "geeksforgeeks",            "wallmart", "walmart",            "waldormort", "word" };     Node* tree = NULL;     // Insert the words in the    // Ternary Search Tree    for (string str : S)        insert(&tree, str);     string pat = "wall";     vector<string> sugg        = autocomplete(tree, pat);     if (sugg.size() == 0)        cout << "None";     else        print(sugg, pat);     return 0;}
wallmart
wallstreet
Time Complexity: O(L* log N) where L is length of longest word. The space is proportional to the length of the string to be stored.Auxiliary Space: O(N)
PrasannaReddyIsireddy
pankajsharmagfg
Trees
Trie
Advanced Data Structure
Algorithms
Competitive Programming
Data Structures
Divide and Conquer
Pattern Searching
Recursion
Searching
Strings
Tree
Data Structures
Searching
Strings
Recursion
Divide and Conquer
Tree
Pattern Searching
Trie
Algorithms
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Ordered Set and GNU C++ PBDS
2-3 Trees | (Search, Insert and Deletion)
Extendible Hashing (Dynamic approach to DBMS)
Suffix Array | Set 1 (Introduction)
Interval Tree
SDE SHEET - A Complete Guide for SDE Preparation
Top 50 Array Coding Problems for Interviews
DSA Sheet by Love Babbar
Difference between BFS and DFS
How to write a Pseudo Code?