Open In App

Pattern Searching using a Trie of all Suffixes

Last Updated : 20 Feb, 2023
Summarize
Comments
Improve
Suggest changes
Like Article
Like
Save
Share
Report
News Follow

Problem Statement: Given a text txt[0..n-1] and a pattern pat[0..m-1], write a function search(char pat[], char txt[]) that prints all occurrences of pat[] in txt[]. You may assume that n > m.
As discussed in the previous post, we discussed that there are two ways efficiently solve the above problem.
1) Preprocess Pattern: KMP Algorithm, Rabin Karp Algorithm, Finite Automata, Boyer Moore Algorithm.
2) Preprocess Text: Suffix Tree

The best possible time complexity achieved by first (preprocessing pattern) is O(n) and by second (preprocessing text) is O(m) where m and n are lengths of pattern and text respectively.
Note that the second way does the searching only in O(m) time and it is preferred when text doesn’t change very frequently and there are many search queries. We have discussed Suffix Tree (A compressed Trie of all suffixes of Text) .
Implementation of Suffix Tree may be time consuming for problems to be coded in a technical interview or programming contexts. In this post simple implementation of a Standard Trie of all Suffixes is discussed. The implementation is close to suffix tree, the only thing is, it’s a simple Trie instead of compressed Trie.

As discussed in Suffix Tree post, the idea is, every pattern that is present in text (or we can say every substring of text) must be a prefix of one of all possible suffixes. So if we build a Trie of all suffixes, we can find the pattern in O(m) time where m is pattern length.

Building a Trie of Suffixes 
1) Generate all suffixes of given text. 
2) Consider all suffixes as individual words and build a trie.
Let us consider an example text “banana\0” where ‘\0’ is string termination character. Following are all suffixes of “banana\0” 
 

banana\0
anana\0
nana\0
ana\0
na\0
a\0
\0

If we consider all of the above suffixes as individual words and build a Trie, we get following. 
 

How to search a pattern in the built Trie? 
Following are steps to search a pattern in the built Trie. 
1) Starting from the first character of the pattern and root of the Trie, do following for every character. 
…..a) For the current character of pattern, if there is an edge from the current node, follow the edge. 
…..b) If there is no edge, print “pattern doesn’t exist in text” and return. 
2) If all characters of pattern have been processed, i.e., there is a path from root for characters of the given pattern, then print all indexes where pattern is present. To store indexes, we use a list with every node that stores indexes of suffixes starting at the node.

Following is the implementation of the above idea.  

C++




// A simple C++ implementation of substring search using trie of suffixes
#include<iostream>
#include<list>
#define MAX_CHAR 256
using namespace std;
 
// A Suffix Trie (A Trie of all suffixes) Node
class SuffixTrieNode
{
private:
    SuffixTrieNode *children[MAX_CHAR];
    list<int> *indexes;
public:
    SuffixTrieNode() // Constructor
    {
        // Create an empty linked list for indexes of
        // suffixes starting from this node
        indexes = new list<int>;
 
        // Initialize all child pointers as NULL
        for (int i = 0; i < MAX_CHAR; i++)
          children[i] = NULL;
    }
 
    // A recursive function to insert a suffix of the txt
    // in subtree rooted with this node
    void insertSuffix(string suffix, int index);
 
    // A function to search a pattern in subtree rooted
    // with this node.The function returns pointer to a linked
    // list containing all indexes where pattern is present.
    // The returned indexes are indexes of last characters
    // of matched text.
    list<int>* search(string pat);
};
 
// A Trie of all suffixes
class SuffixTrie
{
private:
    SuffixTrieNode root;
public:
    // Constructor (Builds a trie of suffixes of the given text)
    SuffixTrie(string txt)
    {
        // Consider all suffixes of given string and insert
        // them into the Suffix Trie using recursive function
        // insertSuffix() in SuffixTrieNode class
        for (int i = 0; i < txt.length(); i++)
            root.insertSuffix(txt.substr(i), i);
    }
 
    // Function to searches a pattern in this suffix trie.
    void search(string pat);
};
 
// A recursive function to insert a suffix of the txt in
// subtree rooted with this node
void SuffixTrieNode::insertSuffix(string s, int index)
{
    // Store index in linked list
    indexes->push_back(index);
 
    // If string has more characters
    if (s.length() > 0)
    {
        // Find the first character
        char cIndex = s.at(0);
 
        // If there is no edge for this character, add a new edge
        if (children[cIndex] == NULL)
            children[cIndex] = new SuffixTrieNode();
 
        // Recur for next suffix
        children[cIndex]->insertSuffix(s.substr(1), index+1);
    }
}
 
// A recursive function to search a pattern in subtree rooted with
// this node
list<int>* SuffixTrieNode::search(string s)
{
    // If all characters of pattern have been processed,
    if (s.length() == 0)
        return indexes;
 
    // if there is an edge from the current node of suffix trie,
    // follow the edge.
    if (children[s.at(0)] != NULL)
        return (children[s.at(0)])->search(s.substr(1));
 
    // If there is no edge, pattern doesn’t exist in text
    else return NULL;
}
 
/* Prints all occurrences of pat in the Suffix Trie S (built for text)*/
void SuffixTrie::search(string pat)
{
    // Let us call recursive search function for root of Trie.
    // We get a list of all indexes (where pat is present in text) in
    // variable 'result'
    list<int> *result = root.search(pat);
 
    // Check if the list of indexes is empty or not
    if (result == NULL)
        cout << "Pattern not found" << endl;
    else
    {
       list<int>::iterator i;
       int patLen = pat.length();
       for (i = result->begin(); i != result->end(); ++i)
         cout << "Pattern found at position " << *i - patLen<< endl;
    }
}
 
// driver program to test above functions
int main()
{
    // Let us build a suffix trie for text "geeksforgeeks.org"
    string txt = "geeksforgeeks.org";
    SuffixTrie S(txt);
 
    cout << "Search for 'ee'" << endl;
    S.search("ee");
 
    cout << "\nSearch for 'geek'" << endl;
    S.search("geek");
 
    cout << "\nSearch for 'quiz'" << endl;
    S.search("quiz");
 
    cout << "\nSearch for 'forgeeks'" << endl;
    S.search("forgeeks");
 
    return 0;
}


Java




import java.util.LinkedList;
import java.util.List;
class SuffixTrieNode {
 
    final static int MAX_CHAR = 256;
 
    SuffixTrieNode[] children = new SuffixTrieNode[MAX_CHAR];
    List<Integer> indexes;
 
    SuffixTrieNode() // Constructor
    {
        // Create an empty linked list for indexes of
        // suffixes starting from this node
        indexes = new LinkedList<Integer>();
 
        // Initialize all child pointers as NULL
        for (int i = 0; i < MAX_CHAR; i++)
            children[i] = null;
    }
 
    // A recursive function to insert a suffix of
    // the text in subtree rooted with this node
    void insertSuffix(String s, int index) {
         
        // Store index in linked list
        indexes.add(index);
 
        // If string has more characters
        if (s.length() > 0) {
         
            // Find the first character
            char cIndex = s.charAt(0);
 
            // If there is no edge for this character,
            // add a new edge
            if (children[cIndex] == null)
                children[cIndex] = new SuffixTrieNode();
 
            // Recur for next suffix
            children[cIndex].insertSuffix(s.substring(1),
                                              index + 1);
        }
    }
 
    // A function to search a pattern in subtree rooted
    // with this node.The function returns pointer to a
    // linked list containing all indexes where pattern 
    // is present. The returned indexes are indexes of 
    // last characters of matched text.
    List<Integer> search(String s) {
         
        // If all characters of pattern have been
        // processed,
        if (s.length() == 0)
            return indexes;
 
        // if there is an edge from the current node of
        // suffix tree, follow the edge.
        if (children[s.charAt(0)] != null)
            return (children[s.charAt(0)]).search(s.substring(1));
 
        // If there is no edge, pattern doesnt exist in
        // text
        else
            return null;
    }
}
 
// A Trie of all suffixes
class Suffix_tree{
 
    SuffixTrieNode root = new SuffixTrieNode();
 
    // Constructor (Builds a trie of suffixes of the
    // given text)
    Suffix_tree(String txt) {
     
        // Consider all suffixes of given string and
        // insert them into the Suffix Trie using
        // recursive function insertSuffix() in
        // SuffixTrieNode class
        for (int i = 0; i < txt.length(); i++)
            root.insertSuffix(txt.substring(i), i);
    }
 
    /* Prints all occurrences of pat in the Suffix Trie S
    (built for text) */
    void search_tree(String pat) {
     
        // Let us call recursive search function for
        // root of Trie.
        // We get a list of all indexes (where pat is
        // present in text) in variable 'result'
        List<Integer> result = root.search(pat);
 
        // Check if the list of indexes is empty or not
        if (result == null)
            System.out.println("Pattern not found");
        else {
 
            int patLen = pat.length();
 
            for (Integer i : result)
                System.out.println("Pattern found at position " +
                                                (i - patLen));
        }
    }
 
    // driver program to test above functions
    public static void main(String args[]) {
         
        // Let us build a suffix trie for text
        // "geeksforgeeks.org"
        String txt = "geeksforgeeks.org";
        Suffix_tree S = new Suffix_tree(txt);
 
        System.out.println("Search for 'ee'");
        S.search_tree("ee");
 
        System.out.println("\nSearch for 'geek'");
        S.search_tree("geek");
 
        System.out.println("\nSearch for 'quiz'");
        S.search_tree("quiz");
 
        System.out.println("\nSearch for 'forgeeks'");
        S.search_tree("forgeeks");
    }
}
// This code is contributed by Sumit Ghosh


C#




// C# implementation of the approach
using System;
using System.Collections.Generic;
class SuffixTrieNode
{
    static int MAX_CHAR = 256;
 
    public SuffixTrieNode[] children = new SuffixTrieNode[MAX_CHAR];
    public List<int> indexes;
 
    public SuffixTrieNode() // Constructor
    {
        // Create an empty linked list for indexes of
        // suffixes starting from this node
        indexes = new List<int>();
 
        // Initialize all child pointers as NULL
        for (int i = 0; i < MAX_CHAR; i++)
            children[i] = null;
    }
 
    // A recursive function to insert a suffix of
    // the text in subtree rooted with this node
    public void insertSuffix(String s, int index)
    {
         
        // Store index in linked list
        indexes.Add(index);
 
        // If string has more characters
        if (s.Length > 0)
        {
         
            // Find the first character
            char cIndex = s[0];
 
            // If there is no edge for this character,
            // add a new edge
            if (children[cIndex] == null)
                children[cIndex] = new SuffixTrieNode();
 
            // Recur for next suffix
            children[cIndex].insertSuffix(s.Substring(1),
                                              index + 1);
        }
    }
 
    // A function to search a pattern in subtree rooted
    // with this node.The function returns pointer to a
    // linked list containing all indexes where pattern
    // is present. The returned indexes are indexes of
    // last characters of matched text.
    public List<int> search(String s)
    {
         
        // If all characters of pattern have been
        // processed,
        if (s.Length == 0)
            return indexes;
 
        // if there is an edge from the current node of
        // suffix tree, follow the edge.
        if (children[s[0]] != null)
            return (children[s[0]]).search(s.Substring(1));
 
        // If there is no edge, pattern doesnt exist in
        // text
        else
            return null;
    }
}
 
// A Trie of all suffixes
public class Suffix_tree
{
 
    SuffixTrieNode root = new SuffixTrieNode();
 
    // Constructor (Builds a trie of suffixes of the
    // given text)
    Suffix_tree(String txt)
    {
     
        // Consider all suffixes of given string and
        // insert them into the Suffix Trie using
        // recursive function insertSuffix() in
        // SuffixTrieNode class
        for (int i = 0; i < txt.Length; i++)
            root.insertSuffix(txt.Substring(i), i);
    }
 
    /* Prints all occurrences of pat in the
    Suffix Trie S (built for text) */
    void search_tree(String pat)
    {
     
        // Let us call recursive search function
        // for root of Trie.
        // We get a list of all indexes (where pat is
        // present in text) in variable 'result'
        List<int> result = root.search(pat);
 
        // Check if the list of indexes is empty or not
        if (result == null)
            Console.WriteLine("Pattern not found");
        else
        {
            int patLen = pat.Length;
 
            foreach (int i in result)
                Console.WriteLine("Pattern found at position " +
                                                  (i - patLen));
        }
    }
 
    // Driver Code
    public static void Main(String []args)
    {
         
        // Let us build a suffix trie for text
        // "geeksforgeeks.org"
        String txt = "geeksforgeeks.org";
        Suffix_tree S = new Suffix_tree(txt);
 
        Console.WriteLine("Search for 'ee'");
        S.search_tree("ee");
 
        Console.WriteLine("\nSearch for 'geek'");
        S.search_tree("geek");
 
        Console.WriteLine("\nSearch for 'quiz'");
        S.search_tree("quiz");
 
        Console.WriteLine("\nSearch for 'forgeeks'");
        S.search_tree("forgeeks");
    }
}
 
// This code is contributed by 29AjayKumar


Javascript




<script>
let MAX_CHAR = 256;
 
class SuffixTrieNode
{
     
    // Constructor
    constructor()   
    {
        this.indexes = [];
        this.children = new Array(MAX_CHAR);
 
        for(let i = 0; i < MAX_CHAR; i++)
        {
            this.children[i] = 0;
        }
    }
     
// A recursive function to insert a suffix of
// the text in subtree rooted with this node
insertSuffix(s,index)
{
     
    // Store index in linked list
    this.indexes.push(index);
 
    // If string has more characters
    if (s.length > 0)
    {
         
        // Find the first character
        let cIndex = s[0];
 
        // If there is no edge for this character,
        // add a new edge
        if (this.children[cIndex] == null)
            this.children[cIndex] = new SuffixTrieNode();
 
        // Recur for next suffix
        this.children[cIndex].insertSuffix(s.substring(1),
                                           index + 1);
    }
}
 
// A function to search a pattern in subtree rooted
// with this node.The function returns pointer to a
// linked list containing all indexes where pattern 
// is present. The returned indexes are indexes of 
// last characters of matched text.
search(s)
{
     
    // If all characters of pattern have been
    // processed,
    if (s.length == 0)
        return this.indexes;
 
    // If there is an edge from the current node of
    // suffix tree, follow the edge.
    if (this.children[s[0]] != null)
        return(this.children[s[0]].search(
                  s.substring(1)));
 
    // If there is no edge, pattern doesnt exist in
    // text
    else
        return null;
}
}
 
let root = new SuffixTrieNode();
 
// Constructor (Builds a trie of suffixes of the
// given text)
function Suffix_tree(txt)
{
     
    // Consider all suffixes of given string and
    // insert them into the Suffix Trie using
    // recursive function insertSuffix() in
    // SuffixTrieNode class
    for(let i = 0; i < txt.length; i++)
        root.insertSuffix(txt.substring(i), i);
}
 
/* Prints all occurrences of pat in the Suffix
Trie S (built for text) */
function search_tree(pat)
{
     
    // Let us call recursive search function for
    // root of Trie.
    // We get a list of all indexes (where pat is
    // present in text) in variable 'result'
    let result = root.search(pat);
 
    // Check if the list of indexes is empty or not
    if (result == null)
        document.write("Pattern not found<br>");
    else
    {
        let patLen = pat.length;
 
        for(let i of result.values())
            document.write("Pattern found at position " +
                           (i - patLen)+"<br>");
    }
}
 
// Driver code
 
// Let us build a suffix trie for text
// "geeksforgeeks.org"
let txt = "geeksforgeeks.org";
Suffix_tree(txt);
 
document.write("Search for 'ee'<br>");
search_tree("ee");
 
document.write("<br>Search for 'geek'<br>");
search_tree("geek");
 
document.write("<br>Search for 'quiz'<br>");
search_tree("quiz");
 
document.write("<br>Search for 'forgeeks'<br>");
search_tree("forgeeks");
 
// This code is contributed by unknown2108
 
</script>


Python3




class SuffixTrieNode:
    def __init__(self):
        self.children = [None] * 256
        self.indexes = []
 
    def insert_suffix(self, suffix, index):
        self.indexes.append(index)
        if suffix:
            c_index = ord(suffix[0])
            if not self.children[c_index]:
                self.children[c_index] = SuffixTrieNode()
            self.children[c_index].insert_suffix(suffix[1:], index + 1)
             
    def search(self, pat):
        if not pat:
            return self.indexes
        c_index = ord(pat[0])
        if self.children[c_index]:
            return self.children[c_index].search(pat[1:])
        return None
 
class SuffixTrie:
    def __init__(self, txt):
        self.root = SuffixTrieNode()
        for i in range(len(txt)):
            self.root.insert_suffix(txt[i:], i)
     
    def search(self, pat):
        result = self.root.search(pat)
        if not result:
            print("Pattern not found")
        else:
            pat_len = len(pat)
            for i in result:
                print(f"Pattern found at position {i - pat_len}")
 
if __name__ == "__main__":
    # Let us build the suffix trie for text "geeksforgeeks.org"
    txt = "geeksforgeeks.org"
    st = SuffixTrie(txt)
 
    # Let us search for different patterns
    pat = "ee"
    print(f"Search for '{pat}'")
    st.search(pat)
    print()
 
    pat = "geek"
    print(f"Search for '{pat}'")
    st.search(pat)
    print()
     
    pat = "quiz"
    print(f"Search for '{pat}'")
    st.search(pat)
    print()
     
    pat = "forgeeks"
    print(f"Search for '{pat}'")
    st.search(pat)
    print()


Output: 

Search for 'ee'
Pattern found at position 1
Pattern found at position 9

Search for 'geek'
Pattern found at position 0
Pattern found at position 8

Search for 'quiz'
Pattern not found

Search for 'forgeeks'
Pattern found at position 5

Time Complexity of the above search function is O(m+k) where m is length of the pattern and k is the number of occurrences of pattern in text.

Space Complexity: O(n * MAX_CHAR) where n is the length of the input text.

 



Previous Article
Next Article

Similar Reads

Sum of decomposition values of all suffixes of an Array
Given an array arr[], the task is to find the sum of the decomposition value of the suffixes subarray.Decomposition Value: The decomposition value of a subarray is the count of the partition in the subarray possible. The partition in the array at index [Tex]i [/Tex]can be done only if the elements of the array before if it less than the current ind
8 min read
Length of all prefixes that are also the suffixes of given string
Given a string S consisting of N characters, the task is to find the length of all prefixes of the given string S that are also suffixes of the same string S. Examples: Input: S = "ababababab"Output: 2 4 6 8Explanation: The prefixes of S that are also its suffixes are: "ab" of length = 2"abab" of length = 4"ababab" of length = 6"abababab" of length
10 min read
Minimize length of a string by removing suffixes and prefixes of same characters
Given a string S of length N consisting only of characters 'a', 'b', and 'c', the task is to minimize the length of the given string by performing the following operations only once: Divide the string into two non-empty substrings and then, append the left substring to the end of the right substring.While appending, if the suffix of the right subst
6 min read
Minimum count of prefixes and suffixes of a string required to form given string
Given two strings str1 and str2, the task is to find the minimum number of prefixes and suffixes of str2 required to form the string str1. If the task is not possible, return "-1". Example: Input: str1 = "HELLOWORLD", str2 = "OWORLDHELL"Output: 2Explanation: The above string can be formed as "HELL" + "OWORLD" which are suffix and prefix of the stri
10 min read
Palindrome check for concatenation of Prefixes and Suffixes
Given an integer N and an array of strings arr[], the task is to check whether the concatenation of prefixes and suffixes of all strings forms a palindrome or not. Examples: Input: N = 4, arr[] = {"bcd", "cd", "a", "d", "abc", "ab"}Output: NoExplanation: "a", "ab" and "abc" are prefixes. "d", "cd" and "bcd" are suffixes. So the final string is "abc
8 min read
Pattern Searching using C++ library
Given a text txt[0..n-1] and a pattern pat[0..m-1], write a function that prints all occurrences of pat[] in txt[]. You may assume that n > m.Examples: Input : txt[] = "geeks for geeks" pat[] = "geeks" Output : Pattern found at index 0 Pattern found at index 10 Input : txt[] = "aaaa" pat[] = "aa" Output : Pattern found at index 0 Pattern found a
3 min read
Pattern Searching using Suffix Tree
Given a text txt[0..n-1] and a pattern pat[0..m-1], write a function search(char pat[], char txt[]) that prints all occurrences of pat[] in txt[]. You may assume that n > m. Preprocess Pattern or Preprocess Text? We have discussed the following algorithms in the previous posts: KMP Algorithm Rabin Karp Algorithm Finite Automata based Algorithm B
4 min read
Real time optimized KMP Algorithm for Pattern Searching
In the article, we have already discussed the KMP algorithm for pattern searching. In this article, a real-time optimized KMP algorithm is discussed. From the previous article, it is known that KMP(a.k.a. Knuth-Morris-Pratt) algorithm preprocesses the pattern P and constructs a failure function F(also called as lps[]) to store the length of the lon
7 min read
Rabin-Karp algorithm for Pattern Searching in Matrix
Given matrices txt[][] of dimensions m1 x m2 and pattern pat[][] of dimensions n1 x n2, the task is to check whether a pattern exists in the matrix or not, and if yes then print the top most indices of the pat[][] in txt[][]. It is assumed that m1, m2 ? n1, n2 Examples: Input: txt[][] = {{G, H, I, P} {J, K, L, Q} {R, G, H, I} {S, J, K, L} } pat[][]
15+ min read
Rabin-Karp Algorithm for Pattern Searching
Given a text T[0. . .n-1] and a pattern P[0. . .m-1], write a function search(char P[], char T[]) that prints all occurrences of P[] present in T[] using Rabin Karp algorithm. You may assume that n > m. Examples: Input: T[] = "THIS IS A TEST TEXT", P[] = "TEST"Output: Pattern found at index 10 Input: T[] = "AABAACAADAABAABA", P[] = "AABA"Output:
15 min read
Optimized Algorithm for Pattern Searching
Question: We have discussed the Naive String matching algorithm here. Consider a situation where all characters of a pattern are different. Can we modify the original Naive String Matching algorithm so that it works better for these types of patterns? If we can, then what are the changes to the original algorithm? Solution: In the original Naive St
7 min read
Pattern Searching | Set 6 (Efficient Construction of Finite Automata)
In the previous post, we discussed the Finite Automata-based pattern searching algorithm. The FA (Finite Automata) construction method discussed in the previous post takes O((m^3)*NO_OF_CHARS) time. FA can be constructed in O(m*NO_OF_CHARS) time. In this post, we will discuss the O(m*NO_OF_CHARS) algorithm for FA construction. The idea is similar t
9 min read
What is Pattern Searching ?
Pattern searching in Data Structures and Algorithms (DSA) is a fundamental concept that involves searching for a specific pattern or sequence of elements within a given data structure. This technique is commonly used in string matching algorithms to find occurrences of a particular pattern within a text or a larger string. By using various algorith
5 min read
Aho-Corasick Algorithm for Pattern Searching
Given an input text and an array of k words, arr[], find all occurrences of all words in the input text. Let n be the length of text and m be the total number of characters in all words, i.e. m = length(arr[0]) + length(arr[1]) + ... + length(arr[k-1]). Here k is total numbers of input words. Example: Input: text = "ahishers" arr[] = {"he", "she",
15+ min read
Boyer Moore Algorithm for Pattern Searching
Pattern searching is an important problem in computer science. When we do search for a string in a notepad/word file, browser, or database, pattern searching algorithms are used to show the search results. A typical problem statement would be-  " Given a text txt[0..n-1] and a pattern pat[0..m-1] where n is the length of the text and m is the lengt
15+ min read
Naive algorithm for Pattern Searching
Given text string with length n and a pattern with length m, the task is to prints all occurrences of pattern in text. Note: You may assume that n > m. Examples:  Input:  text = "THIS IS A TEST TEXT", pattern = "TEST"Output: Pattern found at index 10 Input:  text =  "AABAACAADAABAABA", pattern = "AABA"Output: Pattern found at index 0, Pattern fo
6 min read
Introduction to Pattern Searching
Pattern searching is an algorithm that involves searching for patterns such as strings, words, images, etc. We use certain algorithms to do the search process. The complexity of pattern searching varies from algorithm to algorithm. They are very useful when performing a search in a database. The Pattern Searching algorithm is useful for finding pat
15+ min read
Z algorithm (Linear time pattern searching Algorithm)
This algorithm efficiently locates all instances of a specific pattern within a text in linear time. If the length of the text is "n" and the length of the pattern is "m," then the total time taken is O(m + n), with a linear auxiliary space. It is worth noting that the time and auxiliary space of this algorithm is the same as the KMP algorithm, but
13 min read
Pattern Searching
Pattern searching algorithms are essential tools in computer science and data processing. These algorithms are designed to efficiently find a particular pattern within a larger set of data. Pattern searching algorithms play important role in tasks such as text processing, data mining, and information retrieval. What is Pattern Searching?Pattern sea
4 min read
KMP Algorithm for Pattern Searching
Given two strings txt and pat of size N and M, where N > M. String txt and pat represent the text and pattern respectively. The task is to print all indexes of occurrences of pattern string in the text string. Use one-based indexing while returning the indices. Examples: Input:  txt = "THIS IS A TEST TEXT", pat = "TEST"Output: Pattern found at i
15+ min read
Finite Automata algorithm for Pattern Searching
Given a text txt[0..n-1] and a pattern pat[0..m-1], write a function search(char pat[], char txt[]) that prints all occurrences of pat[] in txt[]. You may assume that n > m.Examples: Input: txt[] = "THIS IS A TEST TEXT" pat[] = "TEST" Output: Pattern found at index 10 Input: txt[] = "AABAACAADAABAABA" pat[] = "AABA" Output: Pattern found at inde
13 min read
Print all possible joints of a Trie constructed from a given list of strings
Given a set of strings str, the task is to print all the joints of the Trie constructed from the given set of strings. Joints of a Trie is the nodes in a trie that have more than one child. Examples: Input: str = {"cat", "there", "caller", "their", "calling"} Output: l, a, e Explanation: root / \ c t | | a h / | | t l e | | \ l i r | \ | | e i r e
11 min read
Sorting array of strings (or words) using Trie | Set-2 (Handling Duplicates)
Given an array of strings, print them in alphabetical (dictionary) order. If there are duplicates in input array, we need to print all the occurrences.Examples: Input : arr[] = { "abc", "xyz", "abcd", "bcd", "abc" } Output : abc abc abcd bcd xyz Input : arr[] = { "geeks", "for", "geeks", "a", "portal", "to", "learn" } Output : a for geeks geeks lea
9 min read
Implement a Dictionary using Trie
Implement a dictionary using Trie such that if the input is a string representing a word, the program prints its meaning from the prebuilt dictionary. Examples: Input: str = "map" Output: a diagrammatic representation of an area Input: str = "language" Output: the method of human communication Approach: We can use a Trie to efficiently store string
9 min read
Trie Data Structure using smart pointer and OOP in C++
We will implement trie using smart pointers in C++ and OOP. Here, We have already discussed the implementation of trie data using recursionIn our implementation node of a trie look like : C/C++ Code class TrieNode{ public: // Use of shared_ptr for storing Children // Pointers of TrieNode shared_ptr children[ALPHABET_SIZE]; // Tracks whether If this
6 min read
Count inversions in an array | Set 4 ( Using Trie )
Inversion Count for an array indicates – how far (or close) the array is from being sorted. If the array is already sorted then inversion count is 0. If the array is sorted in reverse order that inversion count is the maximum. Two elements a[i] and a[j] form an inversion if a[i] > a[j] and i < j. For simplicity, we may assume that all element
12 min read
Print Strings In Reverse Dictionary Order Using Trie
Trie is an efficient information retrieval data structure. Using Trie, search complexities can be brought to an optimal limit. Given an array of strings. The task is to print all strings in reverse dictionary order using Trie. If there are duplicates in the input array, we need to print them only once. Examples: Input: str = {"cat", "there", "calle
12 min read
Spell Checker using Trie
Given an array of strings str[] and a string key, the task is to check if the spelling of the key is correct or not. If found to be true, then print "YES". Otherwise, print the suggested correct spellings. Examples: Input:str[] = { “gee”, “geeks”, “ape”, “apple”, “geeksforgeeks” }, key = “geek” Output: geeks geeksforgeeks Explanation: The string "g
11 min read
Program for assigning usernames using Trie
Suppose there is a queue of n users and your task is to assign a username to them. The system works in the following way. Every user has preferred login in the form of a string 's' s consists only of small case letters and numbers. User name is assigned in the following order s, s0, s1, s2....s11.... means first you check s if s is available assign
15+ min read
Construct a String from another String using Suffix Trie
A suffix tree is a data structure based on trie compression that stores all the suffixes of a given string. Apart from detecting patterns in strings, it has a range of applications in fields like bioinformatics, string algorithms, and data compression. Features of Suffix Trie:A Suffix Trie, commonly referred to as a suffix tree, is a data structure
15+ min read