Count subsequences in first string which are anagrams of the second string
Last Updated :
17 Apr, 2023
Given two strings str1 and str2 of length n1 and n2 respectively. The problem is to count all the subsequences of str1 which are anagrams of str2.
Examples:
Input : str1 = "abacd", str2 = "abc"
Output : 2
Index of characters in the 2 subsequences are:
{0, 1, 3} = {a, b, c} = abc and
{1, 2, 3} = {b, a, c} = bac
The above two subsequences of str1
are anagrams of str2.
Input : str1 = "geeksforgeeks", str2 = "geeks"
Output : 48
Approach: Create two arrays freq1[] and freq2[] each of size '26' implemented as hash tables to store the frequencies of each character of str1 and str2 respectively. Let n1 and n2 be the lengths of str1 and str2 respectively. Now implement the following algorithm:
countSubsequences(str1, str2)
for i = 0 to n1-1
freq1[str1[i] - 'a']++
for i = 0 n2-1
freq2[str2[i] - 'a']++
Initialize count = 1
for i = 0 to 25
if freq2[i] != 0 then
if freq2[i] <= freq1[i] then
count = count * binomialCoeff(freq1[i], freq2[i])
else
return 0
return count
Let freq1[i] is represented as n and freq2[i] as r. Now, binomialCoeff(n, r) mentioned in the algorithm above is nothing but binomial coefficient nCr .Refer this post for its implementation.
Explanation: Let frequency of some character say ch in 'str2' is 'x' and in 'str1' is 'y'. If y < x, then no subsequence of 'str1' exists which could be an anagram of 'str2'. Otherwise, yCx gives the number of occurrences of ch selected which will contribute to the total count of required subsequences.
Implementation:
C++
// C++ implementation to
// count subsequences in
// first string which are
// anagrams of the second
// string
#include <bits/stdc++.h>
using namespace std;
#define SIZE 26
// Returns value of Binomial
// Coefficient C(n, k)
int binomialCoeff(int n, int k)
{
int res = 1;
// Since C(n, k) = C(n, n-k)
if (k > n - k)
k = n - k;
// Calculate value of
// [n * (n-1) *---* (n-k+1)] /
// [k * (k-1) *----* 1]
for (int i = 0; i < k; ++i) {
res *= (n - i);
res /= (i + 1);
}
return res;
}
// function to count subsequences
// in first string which are
// anagrams of the second string
int countSubsequences(string str1, string str2)
{
// hash tables to store frequencies
// of each character
int freq1[SIZE], freq2[SIZE];
int n1 = str1.size();
int n2 = str2.size();
// Initialize
memset(freq1, 0, sizeof(freq1));
memset(freq2, 0, sizeof(freq2));
// store frequency of each
// character of 'str1'
for (int i = 0; i < n1; i++)
freq1[str1[i] - 'a']++;
// store frequency of each
// character of 'str2'
for (int i = 0; i < n2; i++)
freq2[str2[i] - 'a']++;
// to store the total count
// of subsequences
int count = 1;
for (int i = 0; i < SIZE; i++)
// if character (i + 'a')
// exists in 'str2'
if (freq2[i] != 0) {
// if this character's frequency
// in 'str2' in less than or
// equal to its frequency in
// 'str1' then accumulate its
// contribution to the count
// of subsequences. If its
// frequency in 'str1' is 'n'
// and in 'str2' is 'r', then
// its contribution will be nCr,
// where C is the binomial
// coefficient.
if (freq2[i] <= freq1[i])
count = count * binomialCoeff(freq1[i], freq2[i]);
// else return 0 as there could
// be no subsequence which is an
// anagram of 'str2'
else
return 0;
}
// required count of subsequences
return count;
}
// Driver program to test above
int main()
{
string str1 = "abacd";
string str2 = "abc";
cout << "Count = "
<< countSubsequences(str1, str2);
return 0;
}
Java
// Java implementation to
// count subsequences in
// first string which are
// anagrams of the second
// string
import java.util.*;
import java.lang.*;
public class GfG{
public final static int SIZE = 26;
// Returns value of Binomial
// Coefficient C(n, k)
public static int binomialCoeff(int n,
int k)
{
int res = 1;
// Since C(n, k) = C(n, n-k)
if (k > n - k)
k = n - k;
// Calculate value of
// [n * (n-1) *---* (n-k+1)] /
// [k * (k-1) *----* 1]
for (int i = 0; i < k; ++i)
{
res *= (n - i);
res /= (i + 1);
}
return res;
}
// function to count subsequences
// in first string which are
// anagrams of the second string
public static int countSubsequences(String str,
String str3)
{
// hash tables to store frequencies
// of each character
int[] freq1 = new int [SIZE];
int[] freq2 = new int [SIZE];
char[] str1 = str.toCharArray();
char[] str2 = str3.toCharArray();
int n1 = str.length();
int n2 = str3.length();
// store frequency of each
// character of 'str1'
for (int i = 0; i < n1; i++)
freq1[str1[i] - 'a']++;
// store frequency of each
// character of 'str2'
for (int i = 0; i < n2; i++)
freq2[str2[i] - 'a']++;
// to store the total count
// of subsequences
int count = 1;
for (int i = 0; i < SIZE; i++)
// if character (i + 'a')
// exists in 'str2'
if (freq2[i] != 0) {
// if this character's frequency
// in 'str2' in less than or
// equal to its frequency in
// 'str1' then accumulate its
// contribution to the count
// of subsequences. If its
// frequency in 'str1' is 'n'
// and in 'str2' is 'r', then
// its contribution will be nCr,
// where C is the binomial
// coefficient.
if (freq2[i] <= freq1[i])
count = count * binomialCoeff(freq1[i], freq2[i]);
// else return 0 as there could
// be no subsequence which is an
// anagram of 'str2'
else
return 0;
}
// required count of subsequences
return count;
}
// Driver function
public static void main(String argc[])
{
String str1 = "abacd";
String str2 = "abc";
System.out.println("Count = " +
countSubsequences(str1, str2));
}
}
/* This code is contributed by Sagar Shukla */
Python
# Python3 implementation to count
# subsequences in first which are
# anagrams of the second
# import library
import numpy as np
SIZE = 26
# Returns value of Binomial
# Coefficient C(n, k)
def binomialCoeff(n, k):
res = 1
# Since C(n, k) = C(n, n-k)
if (k > n - k):
k = n - k
# Calculate value of
# [n * (n-1) *---* (n-k+1)] /
# [k * (k-1) *----* 1]
for i in range(0, k):
res = res * (n - i)
res = int(res / (i + 1))
return res
# Function to count subsequences
# in first which are anagrams
# of the second
def countSubsequences(str1, str2):
# Hash tables to store frequencies
# of each character
freq1 = np.zeros(26, dtype = np.int)
freq2 = np.zeros(26, dtype = np.int)
n1 = len(str1)
n2 = len(str2)
# Store frequency of each
# character of 'str1'
for i in range(0, n1):
freq1[ord(str1[i]) - ord('a') ] += 1
# Store frequency of each
# character of 'str2'
for i in range(0, n2):
freq2[ord(str2[i]) - ord('a')] += 1
# To store the total count
# of subsequences
count = 1
for i in range(0, SIZE):
# if character (i + 'a')
# exists in 'str2'
if (freq2[i] != 0):
# if this character's frequency
# in 'str2' in less than or
# equal to its frequency in
# 'str1' then accumulate its
# contribution to the count
# of subsequences. If its
# frequency in 'str1' is 'n'
# and in 'str2' is 'r', then
# its contribution will be nCr,
# where C is the binomial
# coefficient.
if (freq2[i] <= freq1[i]):
count = count * binomialCoeff(freq1[i], freq2[i])
# else return 0 as there could
# be no subsequence which is an
# anagram of 'str2'
else:
return 0
# required count of subsequences
return count
# Driver code
str1 = "abacd"
str2 = "abc"
ans = countSubsequences(str1, str2)
print ("Count = ", ans)
# This code contributed by saloni1297
C#
// C# implementation to
// count subsequences in
// first string which are
// anagrams of the second
// string
using System;
class GfG {
public static int SIZE = 26;
// Returns value of Binomial
// Coefficient C(n, k)
public static int binomialCoeff(int n,
int k)
{
int res = 1;
// Since C(n, k) = C(n, n-k)
if (k > n - k)
k = n - k;
// Calculate value of
// [n * (n-1) *---* (n-k+1)] /
// [k * (k-1) *----* 1]
for (int i = 0; i < k; ++i)
{
res *= (n - i);
res /= (i + 1);
}
return res;
}
// function to count subsequences
// in first string which are
// anagrams of the second string
public static int countSubsequences(String str,
String str3)
{
// hash tables to store frequencies
// of each character
int[] freq1 = new int [SIZE];
int[] freq2 = new int [SIZE];
char[] str1 = str.ToCharArray();
char[] str2 = str3.ToCharArray();
int n1 = str.Length;
int n2 = str3.Length;
// store frequency of each
// character of 'str1'
for (int i = 0; i < n1; i++)
freq1[str1[i] - 'a']++;
// store frequency of each
// character of 'str2'
for (int i = 0; i < n2; i++)
freq2[str2[i] - 'a']++;
// to store the total count
// of subsequences
int count = 1;
for (int i = 0; i < SIZE; i++)
// if character (i + 'a')
// exists in 'str2'
if (freq2[i] != 0) {
// if this character's frequency
// in 'str2' in less than or
// equal to its frequency in
// 'str1' then accumulate its
// contribution to the count
// of subsequences. If its
// frequency in 'str1' is 'n'
// and in 'str2' is 'r', then
// its contribution will be nCr,
// where C is the binomial
// coefficient.
if (freq2[i] <= freq1[i])
count = count * binomialCoeff(freq1[i],
freq2[i]);
// else return 0 as there could
// be no subsequence which is an
// anagram of 'str2'
else
return 0;
}
// required count of subsequences
return count;
}
// Driver code
public static void Main(String[] argc)
{
String str1 = "abacd";
String str2 = "abc";
Console.Write("Count = " +
countSubsequences(str1, str2));
}
}
// This code is contributed by parashar
PHP
<?php
// PHP implementation to
// count subsequences in
// first $which are
// anagrams of the second
// string
$SIZE = 26;
// Returns value of Binomial
// Coefficient C(n, k)
function binomialCoeff($n, $k)
{
$res = 1;
// Since C(n, k) = C(n, n-k)
if ($k > $n - $k)
$k = $n - $k;
// Calculate value of
// [n * (n-1) *---* (n-k+1)] /
// [k * (k-1) *----* 1]
for ($i = 0; $i < $k; ++$i)
{
$res *= ($n - $i);
$res /= ($i + 1);
}
return $res;
}
// function to count
// subsequences in
// first string which
// are anagrams of the
// second string
function countSubsequences($str1,
$str2)
{
global $SIZE;
// hash tables to
// store frequencies
// of each character
$freq1 = array();
$freq2 = array();
// Initialize
for ($i = 0;
$i < $SIZE; $i++)
{
$freq1[$i] = 0;
$freq2[$i] = 0;
}
$n1 = strlen($str1);
$n2 = strlen($str2);
// store frequency of each
// character of 'str1'
for ($i = 0; $i < $n1; $i++)
$freq1[ord($str1[$i]) -
ord('a')]++;
// store frequency of each
// character of 'str2'
for ($i = 0; $i < $n2; $i++)
$freq2[ord($str2[$i]) -
ord('a')]++;
// to store the total count
// of subsequences
$count = 1;
for ($i = 0; $i < $SIZE; $i++)
// if character (i + 'a')
// exists in 'str2'
if ($freq2[$i] != 0)
{
// if this character's frequency
// in 'str2' in less than or
// equal to its frequency in
// 'str1' then accumulate its
// contribution to the count
// of subsequences. If its
// frequency in 'str1' is 'n'
// and in 'str2' is 'r', then
// its contribution will be nCr,
// where C is the binomial
// coefficient.
if ($freq2[$i] <= $freq1[$i])
$count = $count *
binomialCoeff($freq1[$i],
$freq2[$i]);
// else return 0 as there
// could be no subsequence
// which is an anagram of
// 'str2'
else
return 0;
}
// required count
// of subsequences
return $count;
}
// Driver Code
$str1 = "abacd";
$str2 = "abc";
echo ("Count = ".
countSubsequences($str1,
$str2));
// This code is contributed by
// Manish Shaw(manishshaw1)
?>
JavaScript
<script>
// JavaScript implementation to
// count subsequences in
// first string which are
// anagrams of the second
// string
var SIZE = 26
// Returns value of Binomial
// Coefficient C(n, k)
function binomialCoeff(n, k)
{
var res = 1;
// Since C(n, k) = C(n, n-k)
if (k > n - k)
k = n - k;
// Calculate value of
// [n * (n-1) *---* (n-k+1)] /
// [k * (k-1) *----* 1]
for (var i = 0; i < k; ++i) {
res *= (n - i);
res /= (i + 1);
}
return res;
}
// function to count subsequences
// in first string which are
// anagrams of the second string
function countSubsequences(str1, str2)
{
// hash tables to store frequencies
// of each character
var freq1 = Array(SIZE).fill(0),
freq2 = Array(SIZE).fill(0);
var n1 = str1.length;
var n2 = str2.length;
// store frequency of each
// character of 'str1'
for (var i = 0; i < n1; i++)
freq1[str1[i].charCodeAt(0) -
'a'.charCodeAt(0)]++;
// store frequency of each
// character of 'str2'
for (var i = 0; i < n2; i++)
freq2[str2[i].charCodeAt(0) -
'a'.charCodeAt(0)]++;
// to store the total count
// of subsequences
var count = 1;
for (var i = 0; i < SIZE; i++)
// if character (i + 'a')
// exists in 'str2'
if (freq2[i] != 0) {
// if this character's frequency
// in 'str2' in less than or
// equal to its frequency in
// 'str1' then accumulate its
// contribution to the count
// of subsequences. If its
// frequency in 'str1' is 'n'
// and in 'str2' is 'r', then
// its contribution will be nCr,
// where C is the binomial
// coefficient.
if (freq2[i] <= freq1[i])
count =
count * binomialCoeff(freq1[i], freq2[i]);
// else return 0 as there could
// be no subsequence which is an
// anagram of 'str2'
else
return 0;
}
// required count of subsequences
return count;
}
// Driver program to test above
var str1 = "abacd";
var str2 = "abc";
document.write( "Count = "
+ countSubsequences(str1, str2));
</script>
Time Complexity: O(n1 + n2) + O(max), where n1 and n2 are the lengths of the input strings and max is the maximum frequency.
Auxiliary space: O(26). The algorithm uses two integer arrays of size 26 to store the frequency of characters in both strings, which takes O(26) space. Also, it uses some constant extra space to store some variables. Therefore, the overall space complexity of the algorithm is O(1).
Similar Reads
Count of strings in the first array which are smaller than every string in the second array
Given two arrays A[] and B[] which consists of N and M strings respectively. A string S1 is said to be smaller than string S2 if the frequency of the smallest character in the S1 is smaller than the frequency of the smallest character in S2. The task is to count the number of strings in A[] which ar
15+ min read
Count the strings that are subsequence of the given string
Given a string S and an array arr[] of words, the task is to return the number of words from the array which is a subsequence of S. Examples: Input: S = âprogrammingâ, arr[] = {"prom", "amin", "proj"}Output: 2Explanation: "prom" and "amin" are subsequence of S while "proj" is not) Input: S = âgeeksf
11 min read
Count of Subsequences of given string X in between strings Y and Z
Given three strings, 'X', 'Y' and 'Z', the task is to count the number of subsequences of 'X' which is lexicographically greater than or equal to 'Y' and lexicographically lesser than or equal to 'Z'. Examples: Input: X = "abc", Y = "a", Z = "bc"Output: 6Explanation: The subsequences of X which are
15+ min read
Remove characters from the first string which are present in the second string
Given two strings string1 and string2, remove those characters from the first string(string1) which are present in the second string(string2). Both strings are different and contain only lowercase characters.NOTE: The size of the first string is always greater than the size of the second string( |st
15+ min read
Count binary Strings that does not contain given String as Subsequence
Given a number N and string S, count the number of ways to create a binary string (containing only '0' and '1') of size N such that it does not contain S as a subsequence. Examples: Input: N = 3, S = "10".Output: 4Explanation: There are 8 strings possible to fill 3 positions with 0's or 1's. {"000",
15+ min read
Find all substrings that are anagrams of another substring of the string S
Given a string S, the task is to find all the substrings in the string S which is an anagram of another different substring in the string S. The different substrings mean the substring starts at a different index. Examples: Input: S = "aba"Output: a a ab baExplanation:Following substrings are anagra
6 min read
Longest common anagram subsequence from N strings
Given N strings. Find the longest possible subsequence from each of these N strings such that they are anagram to each other. The task is to print the lexicographically largest subsequence among all the subsequences. Examples: Input: s[] = { geeks, esrka, efrsk } Output: ske First string has "eks",
11 min read
Count of unique Subsequences of given String with lengths in range [0, N]
Given a string S of length N, the task is to find the number of unique subsequences of the string for each length from 0 to N. Note: The uppercase letters and lowercase letters are considered different and the result may be large so print it modulo 1000000007. Examples: Input: S = "ababd"Output: Num
14 min read
Count of times second string can be formed from the characters of first string
Given two strings str and patt, the task is to find the count of times patt can be formed using the characters of str. Examples: Input: str = "geeksforgeeks", patt = "geeks" Output: 2 "geeks" can be made at most twice from the characters of "geeksforgeeks". Input: str = "abcbca", patt = "aabc" Outpu
6 min read
Count of 'GFG' Subsequences in the given string
Given a string of length n of capital letters. The task is to find the count of 'GFG' subsequence in the given string. Examples: Input : str[] = "GFGFG" Output : 4 GFGFG, GFGFG, GFGFG, GFGFG Input : str[] = "ABCFGFPG" Output : 1 To find the number of "GFG" subsequences in the given string, observe f
5 min read