Count Occurrences of Anagrams
Last Updated :
16 Apr, 2024
Given a word and a text, return the count of the occurrences of anagrams of the word in the text(For eg: anagrams of word for are for, ofr, rof etc.))
Examples:
Input : forxxorfxdofr
for
Output : 3
Explanation : Anagrams of the word for – for, orf, ofr appear in the text and hence the count is 3.
Input : aabaabaa
aaba
Output : 4
Explanation : Anagrams of the word aaba – aaba, abaa each appear twice in the text and hence the count is 4.
A simple approach is to traverse from start of the string considering substrings of length equal to the length of the given word and then check if this substring has all the characters of word.
Implementation:
C++
// A Simple C++ program to count anagrams of a
// pattern in a text.
#include <bits/stdc++.h>
using namespace std;
// Function to find if two strings are equal
bool areAnagram(string s1, string s2)
{
map<char, int> m;
for (int i = 0; i < s1.length(); i++)
m[s1[i]]++;
for (int i = 0; i < s2.length(); i++)
m[s2[i]]--;
for (auto it = m.begin(); it != m.end(); it++)
if (it->second != 0)
return false;
return true;
}
int countAnagrams(string text, string word)
{
// Initialize result
int res = 0;
for (int i = 0; i < text.length() - word.length() + 1;
i++) {
// Check if the word and substring are
// anagram of each other.
if (areAnagram(text.substr(i, word.length()), word))
res++;
}
return res;
}
// Driver Code
int main()
{
string text = "forxxorfxdofr";
string word = "for";
cout << countAnagrams(text, word);
return 0;
}
// This code is contributed by probinsah
Java
// A Simple Java program to count anagrams of a
// pattern in a text.
import java.io.*;
import java.util.*;
public class GFG {
// Function to find if two strings are equal
static boolean araAnagram(String s1, String s2)
{
// converting strings to char arrays
char[] ch1 = s1.toCharArray();
char[] ch2 = s2.toCharArray();
// sorting both char arrays
Arrays.sort(ch1);
Arrays.sort(ch2);
// Check for equality of strings
if (Arrays.equals(ch1, ch2))
return true;
else
return false;
}
static int countAnagrams(String text, String word)
{
int N = text.length();
int n = word.length();
// Initialize result
int res = 0;
for (int i = 0; i <= N - n; i++) {
String s = text.substring(i, i + n);
// Check if the word and substring are
// anagram of each other.
if (araAnagram(word, s))
res++;
}
return res;
}
// Driver code
public static void main(String args[])
{
String text = "forxxorfxdofr";
String word = "for";
System.out.print(countAnagrams(text, word));
}
}
Python3
# A Simple Python program to count anagrams of a
# pattern in a text.
# Function to find if two strings are equal
def areAnagram(s1, s2):
m = {}
for i in range(len(s1)):
if s1[i] not in m:
m[s1[i]] = 1
else:
cnt = m[s1[i]]
m.pop(s1[i])
m[s1[i]] = cnt + 1
for j in range(len(s2)):
if((s2[j] in m) == False):
return False
else:
cnt = m[s2[j]]
m.pop(s2[j])
m[s2[j]] = cnt - 1
for it in m.values():
if(it != 0):
return False
return True
def countAnagrams(text, word):
# Initialize result
res = 0
for i in range(len(text) - len(word)+1):
# Check if the word and substring are
# anagram of each other.
if (areAnagram(text[i:i+len(word)], word)):
res += 1
return res
# Driver Code
text = "forxxorfxdofr"
word = "for"
print(countAnagrams(text, word))
# This code is contributed by shinjanpatra
C#
// C# program to count anagrams of a
// pattern in a text.
using System;
using System.Collections.Generic;
class GFG {
// Function to find if two strings are equal
static bool areAnagram(string first, string second)
{
if (first.Length != second.Length)
return false;
if (first == second)
return true; // or false: Don't know whether a
// string counts as an anagram of
// itself
Dictionary<char, int> pool
= new Dictionary<char, int>();
foreach(
char element in first
.ToCharArray()) // fill the dictionary with
// that available chars and
// count them up
{
if (pool.ContainsKey(element))
pool[element]++;
else
pool.Add(element, 1);
}
foreach(char element in second
.ToCharArray()) // take them out again
{
if (!pool.ContainsKey(
element)) // if a char isn't there at
// all; we're out
return false;
if (--pool[element]
== 0) // if a count is less than zero after
// decrement; we're out
pool.Remove(element);
}
return pool.Count == 0;
}
static int countAnagrams(string text, string word)
{
int N = text.Length;
int n = word.Length;
// Initialize result
int res = 0;
for (int i = 0; i <= N - n; i++) {
string s = text.Substring(i, n);
// Check if the word and substring are
// anagram of each other.
if (areAnagram(word, s) == true) {
res++;
}
}
return res;
}
// Driver code
public static void Main()
{
string text = "forxxorfxdofr";
string word = "for";
Console.Write(countAnagrams(text, word));
}
}
// This code is contributed by Samim Hossain Mondal.
Javascript
<script>// A Simple JavaScript program to count anagrams of a
// pattern in a text.
// Function to find if two strings are equal
function areAnagram(s1, s2)
{
let m = new Map();
for(let i = 0; i < s1.length ; i++)
{
if(m.has(s1[i])===false){
m.set(s1[i],1)
}
else{
let cnt = m.get(s1[i]);
m.delete(s1[i]);
m.set(s1[i],cnt+1);
}
}
for(let j = 0; j < s1.length; j++)
{
if(m.has(s2[j])===false){
return false;
}
else{
let cnt = m.get(s2[j]);
m.delete(s2[j]);
m.set(s2[j],cnt-1);
}
}
for(const it in m.values()){
if(it !== 0)return false
}
return true;
}
function countAnagrams(text, word)
{
// Initialize result
let res = 0;
for(let i = 0;i < text.length - word.length + 1;i++)
{
// Check if the word and substring are
// anagram of each other.
if (areAnagram(text.substring(i, i+word.length), word)) res++;
}
return res;
}
// Driver Code
let text = "forxxorfxdofr";
let word = "for";
document.write(countAnagrams(text, word));
// This code is contributed by shinjanpatra
</script>
Complexity Analysis:
- Time Complexity: O(l1logl1 + l2logl2)
- Auxiliary space: O(l1 + l2).
An Efficient Solution is to use a count array to check for anagrams, we can construct the current count window from the previous window in O(1) time using the sliding window concept.
Implementation:
C++
#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
static int findAnagrams(const std::string& text,
const std::string& word)
{
int text_length = text.length();
int word_length = word.length();
if (text_length < 0 || word_length < 0
|| text_length < word_length)
return 0;
constexpr int CHARACTERS = 256;
int count = 0;
int index = 0;
std::array<char, CHARACTERS> wordArr;
wordArr.fill(0);
std::array<char, CHARACTERS> textArr;
textArr.fill(0);
// till window size
for (; index < word_length; index++) {
wordArr[CHARACTERS - word[index]]++;
textArr[CHARACTERS - text[index]]++;
}
if (wordArr == textArr)
count += 1;
// next window
for (; index < text_length; index++) {
textArr[CHARACTERS - text[index]]++;
textArr[CHARACTERS
- text[index - word_length]]--;
if (wordArr == textArr)
count += 1;
}
return count;
}
};
int main()
{
const std::string& text = "forxxorfxdofr";
const std::string& word = "for";
cout << Solution::findAnagrams(text, word);
return 0;
}
Java
// An efficient Java program to count anagrams of a
// pattern in a text.
import java.io.*;
import java.util.*;
class Solution {
public static int countAnagrams(String s, String p)
{
// change CHARACTERS to support range of supported
// characters
int CHARACTERS = 256;
int sn = s.length();
int pn = p.length();
int count = 0;
if (sn < 0 || pn < 0 || sn < pn)
return 0;
char[] pArr = new char[CHARACTERS];
char[] sArr = new char[CHARACTERS];
int i = 0;
// till window size
for (; i < pn; i++) {
sArr[CHARACTERS - s.charAt(i)]++;
pArr[CHARACTERS - p.charAt(i)]++;
}
if (Arrays.equals(pArr, sArr))
count += 1;
// next window
for (; i < sn; i++) {
sArr[CHARACTERS - s.charAt(i)]++;
sArr[CHARACTERS - s.charAt(i - pn)]--;
if (Arrays.equals(pArr, sArr))
count += 1;
}
return count;
}
// Driver code
public static void main(String args[])
{
String text = "forxxorfxdofr";
String word = "for";
System.out.print(countAnagrams(text, word));
}
}
Python3
# A Simple Python program to count anagrams of a
# pattern in a text with the help of sliding window problem
string = "forxxorfxdofr"
ptr = "for"
n = len(string)
k = len(ptr)
d = {}
for i in ptr:
if i in d:
d[i] += 1
else:
d[i] = 1
i = 0
j = 0
count = len(d)
ans = 0
while j < n:
if string[j] in d:
d[string[j]] -= 1
if d[string[j]] == 0:
count -= 1
if (j-i+1) < k:
j += 1
elif (j-i+1) == k:
if count == 0:
ans += 1
if string[i] in d:
d[string[i]] += 1
if d[string[i]] == 1:
count += 1
i += 1
j += 1
print(ans)
C#
// An efficient C# program to count anagrams of a
// pattern in a text.
using System;
using System.Linq;
class Solution
{
public static int FindAnagrams(string text, string word)
{
int textLength = text.Length;
int wordLength = word.Length;
if (textLength < 0 || wordLength < 0 || textLength < wordLength)
return 0;
// change CHARACTERS to support range of supported
// characters
const int CHARACTERS = 256;
int count = 0;
int index = 0;
char[] wordArr = new char[CHARACTERS];
Array.Fill(wordArr, (char)0);
char[] textArr = new char[CHARACTERS];
Array.Fill(textArr, (char)0);
// till window size
for (; index < wordLength; index++)
{
wordArr[CHARACTERS - word[index]]++;
textArr[CHARACTERS - text[index]]++;
}
if (wordArr.SequenceEqual(textArr))
count += 1;
// next window
for (; index < textLength; index++)
{
textArr[CHARACTERS - text[index]]++;
textArr[CHARACTERS - text[index - wordLength]]--;
if (wordArr.SequenceEqual(textArr))
count += 1;
}
return count;
}
}
class Program
{
static void Main(string[] args)
{
string text = "forxxorfxdofr";
string word = "for";
Console.WriteLine(Solution.FindAnagrams(text, word));
}
}
//This code is contributed by rudra1807raj
Javascript
<script>
// A Simple JavaScript program to count anagrams of a
// pattern in a text with the help of sliding window problem
let string = "forxxorfxdofr"
let ptr = "for"
let n = string.length
let k = ptr.length
let temp = []
let d = new Map();
for(let i = 0; i < ptr.length; i++)
{
if(d.has(ptr[i]))
d.set(ptr[i], d.get(ptr[i])+1)
else
d.set(ptr[i], 1)
}
let i = 0
let j = 0
let count = d.size
let ans = 0
while(j < n)
{
if(d.has(string[j]))
{
d.set(string[j], d.get(string[j]) - 1)
if(d.get(string[j]) == 0)
count--
}
if(j - i + 1 < k)
j++
else if(j - i + 1 == k){
if(count == 0)
ans++
if(d.has(string[i]))
{
d.set(string[i],d.get(string[i])+1)
if(d.get(string[i]) == 1)
count++
}
i++
j++
}
}
document.write(ans)
// This code is contributed by shinjanpatra
</script>
Complexity Analysis:
- Time Complexity: O(l1 + l2)
- Auxiliary space: O(l1 + l2).
Another Approach:
- Compare lengths of two strings, return false if not equal.
- Initialize a map to store character frequencies.
- Increment frequencies of characters in the first string.
- Decrement frequencies of characters in the second string, return false if character not found or frequency becomes negative.
- Return true if all characters have equal frequencies.
- Iterate over text with a sliding window approach.
- For each window, compare if it’s an anagram of the word.
- Increment a counter if an anagram is found.
- Return the counter as the result.
Below is the implementation of the above approach:
C++
#include <iostream>
#include <string>
#include <map>
using namespace std;
// Function to find if two strings are anagrams
bool areAnagram(string s1, string s2) {
if (s1.length() != s2.length())
return false;
map<char, int> freqMap;
// Increment frequency of characters in s1
for (char c : s1)
freqMap[c]++;
// Decrement frequency of characters in s2
for (char c : s2) {
if (freqMap.find(c) == freqMap.end() || freqMap[c] == 0)
return false;
freqMap[c]--;
}
return true;
}
// Function to count occurrences of anagrams of word in text
int countAnagrams(string text, string word) {
int res = 0;
int wordLength = word.length();
int textLength = text.length();
for (int i = 0; i <= textLength - wordLength; ++i) {
string sub = text.substr(i, wordLength);
if (areAnagram(sub, word))
res++;
}
return res;
}
// Driver code
int main() {
string text = "forxxorfxdofr";
string word = "for";
cout << countAnagrams(text, word);
return 0;
}
// Contibuted by kislay__kumar
Java
import java.util.HashMap;
public class AnagramCounter {
// Function to find if two strings are anagrams
public static boolean areAnagram(String s1, String s2) {
if (s1.length() != s2.length())
return false;
HashMap<Character, Integer> freqMap = new HashMap<>();
// Increment frequency of characters in s1
for (char c : s1.toCharArray())
freqMap.put(c, freqMap.getOrDefault(c, 0) + 1);
// Decrement frequency of characters in s2
for (char c : s2.toCharArray()) {
if (!freqMap.containsKey(c) || freqMap.get(c) == 0)
return false;
freqMap.put(c, freqMap.get(c) - 1);
}
return true;
}
// Function to count occurrences of anagrams of word in text
public static int countAnagrams(String text, String word) {
int res = 0;
int wordLength = word.length();
int textLength = text.length();
for (int i = 0; i <= textLength - wordLength; ++i) {
String sub = text.substring(i, i + wordLength);
if (areAnagram(sub, word))
res++;
}
return res;
}
// Driver code
public static void main(String[] args) {
String text = "forxxorfxdofr";
String word = "for";
System.out.println(countAnagrams(text, word));
}
}
Python3
def are_anagram(s1, s2):
if len(s1) != len(s2):
return False
freq_map = {}
# Increment frequency of characters in s1
for c in s1:
freq_map[c] = freq_map.get(c, 0) + 1
# Decrement frequency of characters in s2
for c in s2:
if c not in freq_map or freq_map[c] == 0:
return False
freq_map[c] -= 1
return True
# Function to count occurrences of anagrams of word in text
def count_anagrams(text, word):
res = 0
word_length = len(word)
text_length = len(text)
for i in range(text_length - word_length + 1):
sub = text[i:i + word_length]
if are_anagram(sub, word):
res += 1
return res
# Driver code
text = "forxxorfxdofr"
word = "for"
print(count_anagrams(text, word))
C#
using System;
using System.Collections.Generic;
public class AnagramCounter
{
// Function to find if two strings are anagrams
public static bool AreAnagram(string s1, string s2)
{
if (s1.Length != s2.Length)
return false;
Dictionary<char, int> freqMap = new Dictionary<char, int>();
// Increment frequency of characters in s1
foreach (char c in s1)
freqMap[c] = freqMap.ContainsKey(c) ? freqMap[c] + 1 : 1;
// Decrement frequency of characters in s2
foreach (char c in s2)
{
if (!freqMap.ContainsKey(c) || freqMap[c] == 0)
return false;
freqMap[c]--;
}
return true;
}
// Function to count occurrences of anagrams of word in text
public static int CountAnagrams(string text, string word)
{
int res = 0;
int wordLength = word.Length;
int textLength = text.Length;
for (int i = 0; i <= textLength - wordLength; ++i)
{
string sub = text.Substring(i, wordLength);
if (AreAnagram(sub, word))
res++;
}
return res;
}
// Driver code
public static void Main(string[] args)
{
string text = "forxxorfxdofr";
string word = "for";
Console.WriteLine(CountAnagrams(text, word));
}
}
Javascript
// Function to find if two strings are anagrams
function areAnagram(s1, s2) {
if (s1.length !== s2.length)
return false;
const freqMap = new Map();
// Increment frequency of characters in s1
for (const c of s1)
freqMap.set(c, (freqMap.get(c) || 0) + 1);
// Decrement frequency of characters in s2
for (const c of s2) {
if (!freqMap.has(c) || freqMap.get(c) === 0)
return false;
freqMap.set(c, freqMap.get(c) - 1);
}
return true;
}
// Function to count occurrences of anagrams of word in text
function countAnagrams(text, word) {
let res = 0;
const wordLength = word.length;
const textLength = text.length;
for (let i = 0; i <= textLength - wordLength; ++i) {
const sub = text.substring(i, i + wordLength);
if (areAnagram(sub, word))
res++;
}
return res;
}
// Driver code
const text = "forxxorfxdofr";
const word = "for";
console.log(countAnagrams(text, word));
Time Complexity: O(m * n)
Auxiliary Space: O(n)
Please suggest if someone has a better solution that is more efficient in terms of space and time.
This article is contributed by Aarti_Rathi.
Share your thoughts in the comments
Please Login to comment...