Anagram Substring Search (Or Search for all permutations) | Set 2
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.
Examples:
Input: txt[] = “BACDGABCDA” pat[] = “ABCD”
Output: Found at Index 0
Found at Index 5
Found at Index 6
Input: txt[] = “AAABABAA” pat[] = “AABA”
Output: Found at Index 0
Found at Index 1
Found at Index 4
Approach: The current approach is based on sliding window and hashtable.
- Create a hashtable to store a hash of all characters in the pattern
- Create a hashtable to store a hash of all characters in text for window m
- Traverse the string text in window m and compare the hashtables.
- If found the same, push the index of substring as one of the answers.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
#define MAX 256
using namespace std;
vector< int > findAnagrams(string s, string p)
{
int n = s.length(), m = p.length();
vector< int > ans;
if (n < m || m == 0)
return ans;
vector< int > ms(26, 0), mp(26, 0);
for ( char c : p) {
mp++;
}
int i = 0;
bool flag = true ;
for (i = 0; i < m; i++) {
ms[s[i] - 'A' ]++;
}
for ( int j = 0; j < 26; j++)
if (mp[j] != ms[j])
flag = false ;
if (flag)
ans.push_back(0);
for (i = m; i < n; i++) {
ms[s[i - m] - 'A' ]--;
ms[s[i] - 'A' ]++;
if (mp[s[i] - 'A' ] == ms[s[i] - 'A' ]
&& mp[s[i - m] - 'A' ] == ms[s[i - m] - 'A' ]) {
flag = true ;
for ( int j = 0; j < 26; j++)
if (mp[j] != ms[j])
flag = false ;
}
else
flag = false ;
if (flag)
ans.push_back(i - m + 1);
}
return ans;
}
int main()
{
char txt[] = "BACDGABCDA" ;
char pat[] = "ABCD" ;
vector< int > indices = findAnagrams(txt, pat);
cout << "[ " ;
for ( auto i : indices)
cout << i << " " ;
cout << "]" ;
return 0;
}
|
Java
import java.util.*;
class GFG
{
static final int MAX = 256 ;
static Vector<Integer> findAnagrams(String s, String p)
{
int n = s.length(), m = p.length();
Vector<Integer> ans = new Vector<Integer>();
if (n < m || m == 0 )
return ans;
int [] ms = new int [ 26 ];
int [] mp = new int [ 26 ];
for ( char c : p.toCharArray()) {
mp++;
}
int i = 0 ;
boolean flag = true ;
for (i = 0 ; i < m; i++) {
ms[s.charAt(i) - 'A' ]++;
}
for ( int j = 0 ; j < 26 ; j++)
if (mp[j] != ms[j])
flag = false ;
if (flag)
ans.add( 0 );
for (i = m; i < n; i++) {
ms[s.charAt(i-m) - 'A' ]--;
ms[s.charAt(i) - 'A' ]++;
if (mp[s.charAt(i) - 'A' ] == ms[s.charAt(i) - 'A' ]
&& mp[s.charAt(i-m) - 'A' ] == ms[s.charAt(i-m) - 'A' ]) {
flag = true ;
for ( int j = 0 ; j < 26 ; j++)
if (mp[j] != ms[j])
flag = false ;
}
else
flag = false ;
if (flag)
ans.add(i - m + 1 );
}
return ans;
}
public static void main(String[] args)
{
String txt = "BACDGABCDA" ;
String pat = "ABCD" ;
Vector<Integer> indices = findAnagrams(txt, pat);
System.out.print( "[ " );
for ( int i : indices)
System.out.print(i+ " " );
System.out.print( "]" );
}
}
|
Python3
MAX = 256
def findAnagrams(s, p):
n, m = len (s), len (p)
ans = []
if (n < m or m = = 0 ):
return ans
ms, mp = [ 0 for _ in range ( 26 )], [ 0 for _ in range ( 26 )]
for c in p:
mp[ ord (c) - ord ( 'A' )] + = 1
i = 0
flag = True
for i in range ( 0 , m):
ms[ ord (s[i]) - ord ( 'A' )] + = 1
for j in range ( 0 , 26 ):
if (mp[j] ! = ms[j]):
flag = False
if (flag):
ans.append( 0 )
for i in range (m, n):
ms[ ord (s[i - m]) - ord ( 'A' )] - = 1
ms[ ord (s[i]) - ord ( 'A' )] + = 1
if (mp[ ord (s[i]) - ord ( 'A' )] = = ms[ ord (s[i]) - ord ( 'A' )]
and mp[ ord (s[i - m]) - ord ( 'A' )] = = ms[ ord (s[i - m]) - ord ( 'A' )]):
flag = True
for j in range ( 0 , 26 ):
if (mp[j] ! = ms[j]):
flag = False
else :
flag = False
if (flag):
ans.append(i - m + 1 )
return ans
if __name__ = = "__main__" :
txt = "BACDGABCDA"
pat = "ABCD"
indices = findAnagrams(txt, pat)
print ( "[ " , end = "")
for i in indices:
print (i, end = " " )
print ( "]" )
|
C#
using System;
using System.Collections;
class GFG {
static int MAX = 256;
static ArrayList findAnagrams( string s, string p)
{
int n = s.Length, m = p.Length;
ArrayList ans = new ArrayList();
if (n < m || m == 0)
return ans;
int [] ms = new int [26];
int [] mp = new int [26];
foreach ( char c in p.ToCharArray())
{
mp++;
}
int i = 0;
bool flag = true ;
for (i = 0; i < m; i++) {
ms[s[i] - 'A' ]++;
}
for ( int j = 0; j < 26; j++)
if (mp[j] != ms[j])
flag = false ;
if (flag)
ans.Add(0);
for (i = m; i < n; i++) {
ms[s[i - m] - 'A' ]--;
ms[s[i] - 'A' ]++;
if (mp[s[i] - 'A' ] == ms[s[i] - 'A' ]
&& mp[s[i - m] - 'A' ]
== ms[s[i - m] - 'A' ]) {
flag = true ;
for ( int j = 0; j < 26; j++)
if (mp[j] != ms[j])
flag = false ;
}
else
flag = false ;
if (flag)
ans.Add(i - m + 1);
}
return ans;
}
public static void Main()
{
string txt = "BACDGABCDA" ;
string pat = "ABCD" ;
ArrayList indices = findAnagrams(txt, pat);
Console.Write( "[ " );
foreach ( int i in indices) Console.Write(i + " " );
Console.Write( "]" );
}
}
|
Javascript
<script>
let MAX = 256
function findAnagrams(s, p)
{
let n = s.length, m = p.length;
let ans = [];
if (n < m || m == 0)
return ans;
let ms = new Array(26).fill(0), mp = new Array(26).fill(0);
for (let i = 0; i < p.length; i++) {
mp[p[i].charCodeAt(0) - 'A' .charCodeAt(0)]++;
}
let i = 0;
let flag = true ;
for (i = 0; i < m; i++) {
ms[s[i].charCodeAt(0) - 'A' .charCodeAt(0)]++;
}
for (let j = 0; j < 26; j++)
if (mp[j] != ms[j])
flag = false ;
if (flag)
ans.push(0);
for (i = m; i < n; i++) {
ms[s[i - m].charCodeAt(0) - 'A' .charCodeAt(0)]--;
ms[s[i].charCodeAt(0) - 'A' .charCodeAt(0)]++;
if (mp[s[i].charCodeAt(0) - 'A' .charCodeAt(0)] == ms[s[i].charCodeAt(0) - 'A' .charCodeAt(0)]
&& mp[s[i - m].charCodeAt(0) - 'A' .charCodeAt(0)] == ms[s[i - m].charCodeAt(0) - 'A' .charCodeAt(0)]) {
flag = true ;
for (let j = 0; j < 26; j++)
if (mp[j] != ms[j])
flag = false ;
}
else
flag = false ;
if (flag)
ans.push(i - m + 1);
}
return ans;
}
let txt = "BACDGABCDA" ;
let pat = "ABCD" ;
let indices = findAnagrams(txt, pat);
document.write( "[ " );
for (let i of indices)
document.write(i + " " );
document.write( "]" );
</script>
|
Time complexity: O(N)
Auxiliary Space: O(1)
Last Updated :
10 Mar, 2022
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...