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.
2) Preprocess Text: Suffix Tree
The best possible time complexity achieved by first (preprocssing 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 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
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 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.
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.
This article is contributed by Ashish Anand. Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.
Don’t stop now and take your learning to the next level. Learn all the important concepts of Data Structures and Algorithms with the help of the most trusted course: DSA Self Paced. Become industry ready at a student-friendly price.
- Pattern Searching using C++ library
- KMP Algorithm for Pattern Searching
- Aho-Corasick Algorithm for Pattern Searching
- Naive algorithm for Pattern Searching
- Pattern Searching using Suffix Tree
- Boyer Moore Algorithm for Pattern Searching
- Optimized Naive Algorithm for Pattern Searching
- Finite Automata algorithm for Pattern Searching
- Rabin-Karp Algorithm for Pattern Searching
- Pattern Searching | Set 6 (Efficient Construction of Finite Automata)
- Real time optimized KMP Algorithm for Pattern Searching
- Z algorithm (Linear time pattern searching Algorithm)
- Sum of similarities of string with all of its suffixes
- Trie | (Delete)
- Boggle | Set 2 (Using Trie)
- Implement a Dictionary using Trie
- Search in a trie Recursively
- Insertion in a Trie recursively
- Trie | (Display Content)
- Trie | (Insert and Search)