{"id":25541,"date":"2017-10-25T20:00:56","date_gmt":"2017-10-25T14:30:56","guid":{"rendered":"https:\/\/www.wikitechy.com\/technology\/?p=25541"},"modified":"2017-10-25T20:00:56","modified_gmt":"2017-10-25T14:30:56","slug":"c-programming-pattern-searching-using-trie-suffixes","status":"publish","type":"post","link":"https:\/\/www.wikitechy.com\/technology\/c-programming-pattern-searching-using-trie-suffixes\/","title":{"rendered":"C++ Programming for Pattern Searching using a Trie of all Suffixes"},"content":{"rendered":"<p>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 &gt; m.<\/p>\n<p>As discussed in the previous post, we discussed that there are two ways efficiently solve the above problem.<\/p>\n<p>1) Preprocess Pattern: KMP Algorithm, Rabin Karp Algorithm, Finite Automata, Boyer Moore Algorithm.<\/p>\n<p>2) Preoprocess Text: Suffix Tree<\/p>\n<p>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.<\/p>\n<p>Note that the second way does the searching only in O(m) time and it is preferred when text doesn\u2019t doesn\u2019t change very frequently and there are many search queries. We have discussed Suffix Tree (A compressed Trie of all suffixes of Text) .<\/p>\n[ad type=&#8221;banner&#8221;]\n<p>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\u2019s a simple Trie instead of compressed Trie.<\/p>\n<p>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.<\/p>\n<p>Building a Trie of Suffixes<br \/>\n1) Generate all suffixes of given text.<br \/>\n2) Consider all suffixes as individual words and build a trie.<\/p>\n<p>Let us consider an example text \u201cbanana\\0\u201d where \u2018\\0\u2019 is string termination character. Following are all suffixes of \u201cbanana\\0\u201d<\/p>\n<pre>banana\\0\r\nanana\\0\r\nnana\\0\r\nana\\0\r\nna\\0\r\na\\0\r\n\\0<\/pre>\n<p>If we consider all of the above suffixes as individual words and build a Trie, we get following.<img fetchpriority=\"high\" decoding=\"async\" class=\"aligncenter size-full wp-image-25543\" src=\"https:\/\/www.wikitechy.com\/technology\/wp-content\/uploads\/2017\/05\/suffixtrie.png\" alt=\"C++ Programming for Pattern Searching using a Trie of all Suffixes\" width=\"1006\" height=\"553\" srcset=\"https:\/\/www.wikitechy.com\/technology\/wp-content\/uploads\/2017\/05\/suffixtrie.png 1006w, https:\/\/www.wikitechy.com\/technology\/wp-content\/uploads\/2017\/05\/suffixtrie-300x165.png 300w, https:\/\/www.wikitechy.com\/technology\/wp-content\/uploads\/2017\/05\/suffixtrie-768x422.png 768w, https:\/\/www.wikitechy.com\/technology\/wp-content\/uploads\/2017\/05\/suffixtrie-990x544.png 990w\" sizes=\"(max-width: 1006px) 100vw, 1006px\" \/><\/p>\n<p>&nbsp;<\/p>\n<p><strong>How to search a pattern in the built Trie?<\/strong><br \/>\nFollowing are steps to search a pattern in the built Trie.<br \/>\n<strong>1)<\/strong> Starting from the first character of the pattern and root of the Trie, do following for every character.<br \/>\n\u2026..<strong>a)<\/strong> For the current character of pattern, if there is an edge from the current node, follow the edge.<br \/>\n\u2026..<strong>b)<\/strong> If there is no edge, print \u201cpattern doesn\u2019t exist in text\u201d and return.<br \/>\n<strong>2)<\/strong> 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.<\/p>\n[ad type=&#8221;banner&#8221;]\n<p>Following is C++ implementation of the above idea.<\/p>\n<div class=\"code-embed-wrapper\"> <div class=\"code-embed-infos\"> <span class=\"code-embed-name\">C++<\/span> <\/div> <pre class=\"language-cpp code-embed-pre line-numbers\"  data-start=\"1\" data-line-offset=\"0\"><code class=\"language-cpp code-embed-code\">\/\/ A simple C++ implementation of substring search using trie of suffixes<br\/>#include&lt;iostream&gt;<br\/>#include&lt;list&gt;<br\/>#define MAX_CHAR 256<br\/>using namespace std;<br\/> <br\/>\/\/ A Suffix Trie (A Trie of all suffixes) Node<br\/>class SuffixTrieNode<br\/>{<br\/>private:<br\/>    SuffixTrieNode *children[MAX_CHAR];<br\/>    list&lt;int&gt; *indexes;<br\/>public:<br\/>    SuffixTrieNode() \/\/ Constructor<br\/>    {<br\/>        \/\/ Create an empty linked list for indexes of<br\/>        \/\/ suffixes starting from this node<br\/>        indexes = new list&lt;int&gt;;<br\/> <br\/>        \/\/ Initialize all child pointers as NULL<br\/>        for (int i = 0; i &lt; MAX_CHAR; i++)<br\/>          children[i] = NULL;<br\/>    }<br\/> <br\/>    \/\/ A recursive function to insert a suffix of the txt<br\/>    \/\/ in subtree rooted with this node<br\/>    void insertSuffix(string suffix, int index);<br\/> <br\/>    \/\/ A function to search a pattern in subtree rooted<br\/>    \/\/ with this node.The function returns pointer to a linked<br\/>    \/\/ list containing all indexes where pattern is present.<br\/>    \/\/ The returned indexes are indexes of last characters<br\/>    \/\/ of matched text.<br\/>    list&lt;int&gt;* search(string pat);<br\/>};<br\/> <br\/>\/\/ A Trie of all suffixes<br\/>class SuffixTrie<br\/>{<br\/>private:<br\/>    SuffixTrieNode root;<br\/>public:<br\/>    \/\/ Constructor (Builds a trie of suffies of the given text)<br\/>    SuffixTrie(string txt)<br\/>    {<br\/>        \/\/ Consider all suffixes of given string and insert<br\/>        \/\/ them into the Suffix Trie using recursive function<br\/>        \/\/ insertSuffix() in SuffixTrieNode class<br\/>        for (int i = 0; i &lt; txt.length(); i++)<br\/>            root.insertSuffix(txt.substr(i), i);<br\/>    }<br\/> <br\/>    \/\/ Function to searches a pattern in this suffix trie.<br\/>    void search(string pat);<br\/>};<br\/> <br\/>\/\/ A recursive function to insert a suffix of the txt in<br\/>\/\/ subtree rooted with this node<br\/>void SuffixTrieNode::insertSuffix(string s, int index)<br\/>{<br\/>    \/\/ Store index in linked list<br\/>    indexes-&gt;push_front(index);<br\/> <br\/>    \/\/ If string has more characters<br\/>    if (s.length() &gt; 0)<br\/>    {<br\/>        \/\/ Find the first character<br\/>        char cIndex = s.at(0);<br\/> <br\/>        \/\/ If there is no edge for this character, add a new edge<br\/>        if (children[cIndex] == NULL)<br\/>            children[cIndex] = new SuffixTrieNode();<br\/> <br\/>        \/\/ Recur for next suffix<br\/>        children[cIndex]-&gt;insertSuffix(s.substr(1), index+1);<br\/>    }<br\/>}<br\/> <br\/>\/\/ A recursive function to search a pattern in subtree rooted with<br\/>\/\/ this node<br\/>list&lt;int&gt;* SuffixTrieNode::search(string s)<br\/>{<br\/>    \/\/ If all characters of pattern have been processed,<br\/>    if (s.length() == 0)<br\/>        return indexes;<br\/> <br\/>    \/\/ if there is an edge from the current node of suffix trie,<br\/>    \/\/ follow the edge.<br\/>    if (children[s.at(0)] != NULL)<br\/>        return (children[s.at(0)])-&gt;search(s.substr(1));<br\/> <br\/>    \/\/ If there is no edge, pattern doesn\u2019t exist in text<br\/>    else return NULL;<br\/>}<br\/> <br\/>\/* Prints all occurrences of pat in the Suffix Trie S (built for text)*\/<br\/>void SuffixTrie::search(string pat)<br\/>{<br\/>    \/\/ Let us call recursive search function for root of Trie.<br\/>    \/\/ We get a list of all indexes (where pat is present in text) in<br\/>    \/\/ variable &#039;result&#039;<br\/>    list&lt;int&gt; *result = root.search(pat);<br\/> <br\/>    \/\/ Check if the list of indexes is empty or not<br\/>    if (result == NULL)<br\/>        cout &lt;&lt; &quot;Pattern not found&quot; &lt;&lt; endl;<br\/>    else<br\/>    {<br\/>       list&lt;int&gt;::iterator i;<br\/>       int patLen = pat.length();<br\/>       for (i = result-&gt;begin(); i != result-&gt;end(); ++i)<br\/>         cout &lt;&lt; &quot;Pattern found at position &quot; &lt;&lt; *i - patLen&lt;&lt; endl;<br\/>    }<br\/>}<br\/> <br\/>\/\/ driver program to test above functions<br\/>int main()<br\/>{<br\/>    \/\/ Let us build a suffix trie for text &quot;geeksforgeeks.org&quot;<br\/>    string txt = &quot;geeksforgeeks.org&quot;;<br\/>    SuffixTrie S(txt);<br\/> <br\/>    cout &lt;&lt; &quot;Search for &#039;ee&#039;&quot; &lt;&lt; endl;<br\/>    S.search(&quot;ee&quot;);<br\/> <br\/>    cout &lt;&lt; &quot;\\nSearch for &#039;geek&#039;&quot; &lt;&lt; endl;<br\/>    S.search(&quot;geek&quot;);<br\/> <br\/>    cout &lt;&lt; &quot;\\nSearch for &#039;quiz&#039;&quot; &lt;&lt; endl;<br\/>    S.search(&quot;quiz&quot;);<br\/> <br\/>    cout &lt;&lt; &quot;\\nSearch for &#039;forgeeks&#039;&quot; &lt;&lt; endl;<br\/>    S.search(&quot;forgeeks&quot;);<br\/> <br\/>    return 0;<br\/>}<\/code><\/pre> <\/div>\n<p><strong>Output:<\/strong><\/p>\n<pre>Search for 'ee'\r\nPattern found at position 9\r\nPattern found at position 1\r\n\r\nSearch for 'geek'\r\nPattern found at position 8\r\nPattern found at position 0\r\n\r\nSearch for 'quiz'\r\nPattern not found\r\n\r\nSearch for 'forgeeks'\r\nPattern found at position 5\r\n<\/pre>\n<p>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.<\/p>\n[ad type=&#8221;banner&#8221;]\n","protected":false},"excerpt":{"rendered":"<p>C++ Programming for Pattern Searching using a Trie of all Suffixes &#8211; Searching and Sorting &#8211; Implementation of Suffix Tree may be time consuming for problem<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[83515,1,71670],"tags":[73783,73798,73819,73805,70048,73336,73811,71386,73786,73789,73792,73796,73649,73809,73794,73598,73800,73793,73817,73818,73806,73803,73808,73787,73799,73807,73820,73814,73804,73813,73644,73801,73797,73812,73781,73784,73788,73636,73632,73815,73810,73791,73795,73821,70657,73802,73785,73790,73816,73782],"class_list":["post-25541","post","type-post","status-publish","format-standard","hentry","category-c-programming-3","category-coding","category-searching-and-sorting","tag-association-rule-mining","tag-association-rule-mining-example","tag-data-structure-diagram","tag-data-structure-tutorial-point","tag-data-structures","tag-data-structures-and-algorithms-in-java","tag-data-structures-and-algorithms-in-java-interview-questions","tag-data-structures-and-algorithms-in-java-tutorial","tag-data-structures-in-java","tag-data-structures-in-java-examples","tag-data-structures-java","tag-data-structures-using-java","tag-data-suffix","tag-do-suffix","tag-examples-of-data-structures","tag-faststring","tag-fp-growth-algorithm","tag-fp-growth-algorithm-in-data-mining","tag-fp-tree","tag-frequent-itemset","tag-implementation-of-data-structures-in-java","tag-implements-java","tag-java-data","tag-java-data-structures","tag-java-data-structures-interview-questions","tag-java-struct","tag-java-struct-example","tag-java-tree","tag-prefix-word-search","tag-prefix-word-search-printable","tag-search-suffix","tag-search-trie","tag-sequence-mining","tag-spark-router","tag-splay-tree-visualization","tag-struct-in-java","tag-structure-of-java-program","tag-suffix","tag-suffix-array-java","tag-suffix-of-create","tag-suffix-tree-clustering","tag-tire-size","tag-tree-data-structure-tutorial","tag-tree-implementation-in-java-source-code","tag-tree-java","tag-trie-data-structure-pdf","tag-try","tag-what-is-a-data-structure","tag-what-is-a-trie-data-structure","tag-what-is-data-structure"],"_links":{"self":[{"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/posts\/25541","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/comments?post=25541"}],"version-history":[{"count":0,"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/posts\/25541\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/media?parent=25541"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/categories?post=25541"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/tags?post=25541"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}