Anagram Substring Search (Or Search for all permutations) - GeeksforGeeks

07 Jul, 2021
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[] and its permutations (or anagrams) in txt[]. You may assume that n > m. Expected time complexity is O(n)Examples: 
1) Input:  txt[] = "BACDGABCDA"  pat[] = "ABCD"
   Output:   Found at Index 0
             Found at Index 5
             Found at Index 6
2) Input: txt[] =  "AAABABAA" pat[] = "AABA"
   Output:   Found at Index 0
             Found at Index 1
             Found at Index 4
 
This problem is slightly different from standard pattern searching problem, here we need to search for anagrams as well. Therefore, we cannot directly apply standard pattern searching algorithms like KMP, Rabin Karp, Boyer Moore, etc.A simple idea is to modify Rabin Karp Algorithm. For example, we can keep the hash value as sum of ASCII values of all characters under modulo of a big prime number. For every character of text, we can add the current character to hash value and subtract the first character of previous window. This solution looks good, but like standard Rabin Karp, the worst case time complexity of this solution is O(mn). The worst case occurs when all hash values match and we one by one match all characters.We can achieve O(n) time complexity under the assumption that alphabet size is fixed which is typically true as we have maximum 256 possible characters in ASCII. The idea is to use two count arrays: 1) The first count array store frequencies of characters in pattern. 2) The second count array stores frequencies of characters in current window of text.The important thing to note is, time complexity to compare two count arrays is O(1) as the number of elements in them are fixed (independent of pattern and text sizes). Following are steps of this algorithm. 1) Store counts of frequencies of pattern in first count array countP[]. Also store counts of frequencies of characters in first window of text in array countTW[].2) Now run a loop from i = M to N-1. Do following in loop. .....a) If the two count arrays are identical, we found an occurrence. .....b) Increment count of current character of text in countTW[] .....c) Decrement count of first character in previous window in countWT[]3) The last window is not checked by above loop, so explicitly check it.Following is the implementation of above algorithm.  
C++
Java
Python3
C#
Javascript
// C++ program to search all anagrams of a pattern in a text#include<iostream>#include<cstring>#define MAX 256using namespace std; // This function returns true if contents of arr1[] and arr2[]// are same, otherwise false.bool compare(char arr1[], char arr2[]){    for (int i=0; i<MAX; i++)        if (arr1[i] != arr2[i])            return false;    return true;} // This function search for all permutations of pat[] in txt[]void search(char *pat, char *txt){    int M = strlen(pat), N = strlen(txt);     // countP[]:  Store count of all characters of pattern    // countTW[]: Store count of current window of text    char countP[MAX] = {0}, countTW[MAX] = {0};    for (int i = 0; i < M; i++)    {        (countP[pat[i]])++;        (countTW[txt[i]])++;    }     // Traverse through remaining characters of pattern    for (int i = M; i < N; i++)    {        // Compare counts of current window of text with        // counts of pattern[]        if (compare(countP, countTW))            cout << "Found at Index " << (i - M) << endl;         // Add current character to current window        (countTW[txt[i]])++;         // Remove the first character of previous window        countTW[txt[i-M]]--;    }     // Check for the last window in text    if (compare(countP, countTW))        cout << "Found at Index " << (N - M) << endl;} /* Driver program to test above function */int main(){    char txt[] = "BACDGABCDA";    char pat[] = "ABCD";    search(pat, txt);    return 0;}
// Java program to search all anagrams// of a pattern in a textpublic class GFG{    static final int MAX = 256;         // This function returns true if contents    // of arr1[] and arr2[] are same, otherwise    // false.    static boolean compare(char arr1[], char arr2[])    {        for (int i = 0; i < MAX; i++)            if (arr1[i] != arr2[i])                return false;        return true;    }     // This function search for all permutations    // of pat[] in txt[]    static void search(String pat, String txt)    {        int M = pat.length();        int N = txt.length();         // countP[]:  Store count of all        // characters of pattern        // countTW[]: Store count of current        // window of text        char[] countP = new char[MAX];        char[] countTW = new char[MAX];        for (int i = 0; i < M; i++)        {            (countP[pat.charAt(i)])++;            (countTW[txt.charAt(i)])++;        }         // Traverse through remaining characters        // of pattern        for (int i = M; i < N; i++)        {            // Compare counts of current window            // of text with counts of pattern[]            if (compare(countP, countTW))                System.out.println("Found at Index " +                                          (i - M));                         // Add current character to current            // window            (countTW[txt.charAt(i)])++;             // Remove the first character of previous            // window            countTW[txt.charAt(i-M)]--;        }         // Check for the last window in text        if (compare(countP, countTW))            System.out.println("Found at Index " +                                       (N - M));    }     /* Driver program to test above function */    public static void main(String args[])    {        String txt = "BACDGABCDA";        String pat = "ABCD";        search(pat, txt);    }}// This code is contributed by Sumit Ghosh
# Python program to search all# anagrams of a pattern in a text MAX=256 # This function returns true# if contents of arr1[] and arr2[]# are same, otherwise false.def compare(arr1, arr2):    for i in range(MAX):        if arr1[i] != arr2[i]:            return False    return True     # This function search for all# permutations of pat[] in txt[] def search(pat, txt):     M = len(pat)    N = len(txt)     # countP[]:  Store count of    # all characters of pattern    # countTW[]: Store count of    # current window of text    countP = [0]*MAX     countTW = [0]*MAX     for i in range(M):        (countP[ord(pat[i]) ]) += 1        (countTW[ord(txt[i]) ]) += 1     # Traverse through remaining    # characters of pattern    for i in range(M,N):         # Compare counts of current        # window of text with        # counts of pattern[]        if compare(countP, countTW):            print("Found at Index", (i-M))         # Add current character to current window        (countTW[ ord(txt[i]) ]) += 1         # Remove the first character of previous window        (countTW[ ord(txt[i-M]) ]) -= 1         # Check for the last window in text       if compare(countP, countTW):        print("Found at Index", N-M)         # Driver program to test above function      txt = "BACDGABCDA"pat = "ABCD"      search(pat, txt)   # This code is contributed# by Upendra Singh Bartwal
// C# program to search all anagrams// of a pattern in a textusing System; class GFG{public const int MAX = 256; // This function returns true if // contents of arr1[] and arr2[]// are same, otherwise false.public static bool compare(char[] arr1,                           char[] arr2){    for (int i = 0; i < MAX; i++)    {        if (arr1[i] != arr2[i])        {            return false;        }    }    return true;} // This function search for all// permutations of pat[] in txt[]public static void search(string pat,                          string txt){    int M = pat.Length;    int N = txt.Length;     // countP[]: Store count of all    // characters of pattern    // countTW[]: Store count of current    // window of text    char[] countP = new char[MAX];    char[] countTW = new char[MAX];    for (int i = 0; i < M; i++)    {        (countP[pat[i]])++;        (countTW[txt[i]])++;    }     // Traverse through remaining    // characters of pattern    for (int i = M; i < N; i++)    {        // Compare counts of current window        // of text with counts of pattern[]        if (compare(countP, countTW))        {            Console.WriteLine("Found at Index " +                             (i - M));        }         // Add current character to        // current window        (countTW[txt[i]])++;         // Remove the first character of        // previous window        countTW[txt[i - M]]--;    }     // Check for the last window in text    if (compare(countP, countTW))    {        Console.WriteLine("Found at Index " +                         (N - M));    }} // Driver Codepublic static void Main(string[] args){    string txt = "BACDGABCDA";    string pat = "ABCD";    search(pat, txt);}} // This code is contributed// by Shrikant1
<script>       // JavaScript program to search all anagrams      // of a pattern in a text      const MAX = 256;       // This function returns true if      // contents of arr1[] and arr2[]      // are same, otherwise false.      function compare(arr1, arr2) {        for (var i = 0; i < MAX; i++) {          if (arr1[i] !== arr2[i]) {            return false;          }        }        return true;      }       // This function search for all      // permutations of pat[] in txt[]      function search(pat, txt) {        var M = pat.length;        var N = txt.length;         // countP[]: Store count of all        // characters of pattern        // countTW[]: Store count of current        // window of text        var countP = new Array(MAX).fill(0);        var countTW = new Array(MAX).fill(0);        for (var i = 0; i < M; i++) {          countP[pat[i].charCodeAt(0)]++;          countTW[txt[i].charCodeAt(0)]++;        }         // Traverse through remaining        // characters of pattern        for (var i = M; i < N; i++) {          // Compare counts of current window          // of text with counts of pattern[]          if (compare(countP, countTW)) {            document.write("Found at Index " + (i - M) + "<br>");          }           // Add current character to          // current window          countTW[txt[i].charCodeAt(0)]++;           // Remove the first character of          // previous window          countTW[txt[i - M].charCodeAt(0)]--;        }         // Check for the last window in text        if (compare(countP, countTW)) {          document.write("Found at Index " + (N - M) + "<br>");        }      }       // Driver Code      var txt = "BACDGABCDA";      var pat = "ABCD";      search(pat, txt);       </script>
Output:  
Found at Index 0
Found at Index 5
Found at Index 6
 
YouTubeGeeksforGeeks500K subscribersAnagram Substring Search (Or Search for all permutations) | GeeksforGeeksWatch laterShareCopy linkInfoShoppingTap to unmuteIf playback doesn't begin shortly, try restarting your device.You're signed outVideos you watch may be added to the TV's watch history and influence TV recommendations. To avoid this, cancel and sign in to YouTube on your computer.CancelConfirmMore videosMore videosSwitch cameraShareInclude playlistAn error occurred while retrieving sharing information. Please try again later.Watch on0:000:000:00 / 6:41•Live•<div class="player-unavailable"><h1 class="message">An error occurred.</h1><div class="submessage"><a href="https://www.youtube.com/watch?v=-rcfE1Tj2E0" target="_blank">Try watching this video on www.youtube.com</a>, or enable JavaScript if it is disabled in your browser.</div></div>
This article is contributed by Piyush Gupta. Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above 
 
disha22
shrikanth13
gp6
rdtank
Amazon
anagram
Microsoft
permutation
sliding-window
Arrays
Pattern Searching
Amazon
Microsoft
sliding-window
Arrays
permutation
Pattern Searching
anagram
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Comments
Old Comments
Arrays in Java
Arrays in C/C++
Program for array rotation
Stack Data Structure (Introduction and Program)
Top 50 Array Coding Problems for Interviews
Check if a string is substring of another
Check if an URL is valid or not using Regular Expression
Wildcard Pattern Matching
Check if a string contains uppercase, lowercase, special characters and numeric values
Search a Word in a 2D Grid of characters