Open In App

Count of strings that contains every String of another Array as Subset

Last Updated : 27 Jul, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given two arrays of strings A[] and B[] containing only small case letters, the task is to count the number of strings in A[] such that it contains every string of array B[] as a subset (ordering of characters does not matter).

Examples:

Input: A[] = {“geeks”, “gfg”}, B[] = {“g”, “gf”}
Output: 1
Explanation: “gfg” in array A[] is the only string 
that has both “g” and “gf”.

Input: A[] = {“geekolymic”, “google”, “amazon”},  B[] = {“og” } 
Output:
Explanation: “geekolymic” and “google” both contains “og” as subset.

Approach:

The condition for all strings of B to be present as a subset in a string of array A is: 

  • Maximum frequency of every letter of B ≤ frequency of every letter of B in A[i].

Follow the steps to solve this problem:

  • Create a max_freq[] array to store the maximum frequency of each letter in words of B.
  • For each word in B, calculate the frequency of each letter in that word and update the max_freq[] array.
  • Initialize a variable ans = 0, now for every word in A[], calculate the frequency of each character in a temp[] array.
  • For each letter in that word if max_freq[i] <= temp[i], increment the ans.
  • Return the ans.

Below is the implementation of the above approach : 

C++14




// C++ code to implement the approach
#include <bits/stdc++.h>
using namespace std;
 
// Function to calculate the number of words
// in A, that has every word of B as subset
int countcommon(vector<string> A, vector<string> B, int N,
                int M)
{
 
    // array to store maximum frequency of
    // characters of array B count of B[i]
    // which matches the condition
    int max_freq[26] = { 0 };
    int ans = 0;
    for (int i = 0; i < M; i++) {
        int temp[26] = { 0 };
        for (int j = 0; j < B[i].size(); j++) {
            temp[B[i][j] - 'a']++;
        }
        for (int k = 0; k < 26; k++) {
            max_freq[k] = max(max_freq[k], temp[k]);
        }
    }
 
    // Iterate in array a and check for condition
    // max_freq[i]<=frequency of every a[i][j]
    for (int i = 0; i < N; i++) {
        int temp[26] = { 0 };
        for (int j = 0; j < A[i].size(); j++) {
            temp[A[i][j] - 'a']++;
        }
        bool f = false;
        for (int k = 0; k < 26; k++) {
            if (max_freq[k] > temp[k]) {
                f = true;
                break;
            }
        }
        if (f == false)
            ans++;
    }
 
    // Return the answer
    return ans;
}
 
// Driver Code
int main()
{
    vector<string> A{ "geekolymic", "google", "amazon" };
    vector<string> B{ "go" };
    int N = A.size();
    int M = B.size();
    cout << countcommon(A, B, N, M) << endl;
    return 0;
}


Java




/*package whatever //do not write package name here */
 
import java.io.*;
import java.util.*;
 
class GFG {
   
// Function to calculate the number of words
// in A, that has every word of B as subset
static int countcommon(String[] A, String[] B, int N, int M)
{
 
    // array to store maximum frequency of
    // characters of array B count of B[i]
    // which matches the condition
    int max_freq[] = new int[26];
    int ans = 0;
    for (int i = 0; i < M; i++) {
        int temp[] = new int[26];
        for (int j = 0; j < B[i].length(); j++) {
            temp[B[i].charAt(j) - 'a']++;
        }
        for (int k = 0; k < 26; k++) {
            max_freq[k] = Math.max(max_freq[k], temp[k]);
        }
    }
 
    // Iterate in array a and check for condition
    // max_freq[i]<=frequency of every a[i][j]
    for (int i = 0; i < N; i++) {
        int temp[] = new int[26];
        for (int j = 0; j < A[i].length(); j++) {
            temp[A[i].charAt(j) - 'a']++;
        }
        boolean check = false;
        for (int k = 0; k < 26; k++) {
            if (max_freq[k] > temp[k]) {
                check = true;
                break;
            }
        }
        if (!check)
            ans++;
    }
 
    // Return the answer
    return ans;
}
   
    public static void main (String[] args) {
        String A[] = { "geekolymic", "google", "amazon" };
        String B[] = { "go" };
        int N = A.length;
        int M = B.length;
        System.out.println(countcommon(A, B, N, M));
    }
}
 
// This code is contributed by aadityapburujwale


Python3




# python3 code to implement the approach
 
# Function to calculate the number of words
# in A, that has every word of B as subset
from random import randrange
 
 
def countcommon(A, B, N, M):
 
    # array to store maximum frequency of
    # characters of array B count of B[i]
    # which matches the condition
    max_freq = [0 for _ in range(26)]
    ans = 0
    for i in range(0, M):
        temp = [0 for _ in range(26)]
        for j in range(0, len(B[i])):
            temp[ord(B[i][j]) - ord('a')] += 1
 
        for k in range(0, 26):
            max_freq[k] = max(max_freq[k], temp[k])
 
    # Iterate in array a and check for condition
    # max_freq[i]<=frequency of every a[i][j]
    for i in range(0, N):
        temp = [0 for _ in range(26)]
        for j in range(0, len(A[i])):
            temp[ord(A[i][j]) - ord('a')] += 1
 
        f = False
        for k in range(0, k):
            if (max_freq[k] > temp[k]):
                f = True
                break
 
        if (f == False):
            ans += 1
 
    # Return the answer
    return ans
 
 
# Driver Code
if __name__ == "__main__":
 
    A = ["geekolymic", "google", "amazon"]
    B = ["go"]
    N = len(A)
    M = len(B)
    print(countcommon(A, B, N, M))
 
    # This code is contributed by rakeshsahni


C#




/*package whatever //do not write package name here */
 
 
using System;
 
public class GFG {
   
// Function to calculate the number of words
// in A, that has every word of B as subset
static int countcommon(String[] A, String[] B, int N, int M)
{
 
    // array to store maximum frequency of
    // characters of array B count of B[i]
    // which matches the condition
    int []max_freq = new int[26];
    int ans = 0;
    for (int i = 0; i < M; i++) {
        int []temp = new int[26];
        for (int j = 0; j < B[i].Length; j++) {
            temp[B[i][j] - 'a']++;
        }
        for (int k = 0; k < 26; k++) {
            max_freq[k] = Math.Max(max_freq[k], temp[k]);
        }
    }
 
    // Iterate in array a and check for condition
    // max_freq[i]<=frequency of every a[i,j]
    for (int i = 0; i < N; i++) {
        int []temp = new int[26];
        for (int j = 0; j < A[i].Length; j++) {
            temp[A[i][j] - 'a']++;
        }
        bool check = false;
        for (int k = 0; k < 26; k++) {
            if (max_freq[k] > temp[k]) {
                check = true;
                break;
            }
        }
        if (!check)
            ans++;
    }
 
    // Return the answer
    return ans;
}
   
    public static void Main(String[] args) {
        String []A = { "geekolymic", "google", "amazon" };
        String []B = { "go" };
        int N = A.Length;
        int M = B.Length;
        Console.WriteLine(countcommon(A, B, N, M));
    }
}
 
 
// This code contributed by shikhasingrajput


Javascript




<script>
    // JavaScript program for the above approach
 
// Function to calculate the number of words
// in A, that has every word of B as subset
function countcommon(A, B, N, M)
{
 
    // array to store maximum frequency of
    // characters of array B count of B[i]
    // which matches the condition
    let max_freq = new Array(26);
    let ans = -1;
    for (let i = 0; i < M; i++) {
        let temp = new Array(26);
        for (let j = 0; j < B[i].length; j++) {
            temp[B[i][j] - 'a']++;
        }
        for (let k = 0; k < 26; k++) {
            max_freq[k] = Math.max(max_freq[k], temp[k]);
        }
    }
 
    // Iterate in array a and check for condition
    // max_freq[i]<=frequency of every a[i,j]
    for (let i = 0; i < N; i++) {
        let temp = new Array(26);
        for (let j = 0; j < A[i].length; j++) {
            temp[A[i][j] - 'a']++;
        }
        let check = false;
        for (let k = 0; k < 26; k++) {
            if (max_freq[k] > temp[k]) {
                check = true;
                break;
            }
        }
        if (!check)
            ans++;
    }
 
    // Return the answer
    return ans;
}
 
    // Driver code
 
        let A = [ "geekolymic", "google", "amazon" ];
        let B = [ "go" ];
        let N = A.length;
        let M = B.length;
        document.write(countcommon(A, B, N, M));
 
// This code is contributed by sanjoy_62.
</script>


Output

2

Time Complexity: O(max(N, M)*26), where N is the size of A and M is the size of B
Auxiliary Space: O(26)

Another Approach:

  • Initialize a frequency array freqB of size 26 (for small case letters) with all elements as 0.
  • Traverse the array B[] and for each string, update the frequency array by incrementing the count of characters present in that string.
    Initialize a variable count to 0.
    Traverse the array A[] and for each string, initialize a frequency array freqA of size 26 with all elements as 0.
  • Traverse the current string of A[] and for each character, update the frequency array freqA by incrementing the count of that character.
  • Traverse the frequency array freqB and for each non-zero element, check if the corresponding element in freqA is greater than or equal to the frequency in freqB. If not, break from the loop and move to the next string of A[].
  • If all the elements in freqB are present in freqA, increment the count variable.
  • Return the count variable as the result.

Below is the implementation of the above approach : 

C++




// C++ code to implement the approach
#include <bits/stdc++.h>
using namespace std;
 
int countcommon(vector<string> A, vector<string> B, int N, int M)
{
    int freqB[26] = {0};
    for (int i = 0; i < M; i++) {
        string curr = B[i];
        for (int j = 0; j < curr.length(); j++) {
            freqB[curr[j] - 'a']++;
        }
    }
    int count = 0;
    for (int i = 0; i < N; i++) {
        int freqA[26] = {0};
        string curr = A[i];
        for (int j = 0; j < curr.length(); j++) {
            freqA[curr[j] - 'a']++;
        }
        bool flag = true;
        for (int j = 0; j < 26; j++) {
            if (freqB[j] != 0 && freqA[j] < freqB[j]) {
                flag = false;
                break;
            }
        }
        if (flag) {
            count++;
        }
    }
    return count;
}
 
// Driver Code
int main()
{
    vector<string> A{ "geekolymic", "google", "amazon" };
    vector<string> B{ "go" };
    int N = A.size();
    int M = B.size();
    cout << countcommon(A, B, N, M) << endl;
    return 0;
}


Java




/*package whatever //do not write package name here */
 
// Java code to implement the approach
import java.util.*;
 
class Main {
  static int countcommon(List<String> A, List<String> B,
                         int N, int M)
  {
    int freqB[] = new int[26];
    for (int i = 0; i < M; i++) {
      String curr = B.get(i);
      for (int j = 0; j < curr.length(); j++) {
        freqB[curr.charAt(j) - 'a']++;
      }
    }
    int count = 0;
    for (int i = 0; i < N; i++) {
      int freqA[] = new int[26];
      String curr = A.get(i);
      for (int j = 0; j < curr.length(); j++) {
        freqA[curr.charAt(j) - 'a']++;
      }
      boolean flag = true;
      for (int j = 0; j < 26; j++) {
        if (freqB[j] != 0 && freqA[j] < freqB[j]) {
          flag = false;
          break;
        }
      }
      if (flag) {
        count++;
      }
    }
    return count;
  }
 
  // Driver code
  public static void main(String[] args)
  {
    List<String> A
      = new ArrayList<String>(Arrays.asList(
        "geekolymic", "google", "amazon"));
    List<String> B
      = new ArrayList<String>(Arrays.asList("go"));
    int N = A.size();
    int M = B.size();
    System.out.println(countcommon(A, B, N, M));
  }
}
 
// This code is contributed by akashish__


Python3




def countcommon(A, B, N, M):
    freqB = [0] * 26
    for i in range(M):
        curr = B[i]
        for j in range(len(curr)):
            freqB[ord(curr[j]) - ord('a')] += 1
 
    count = 0
    for i in range(N):
        freqA = [0] * 26
        curr = A[i]
        for j in range(len(curr)):
            freqA[ord(curr[j]) - ord('a')] += 1
 
        flag = True
        for j in range(26):
            if freqB[j] != 0 and freqA[j] < freqB[j]:
                flag = False
                break
 
        if flag:
            count += 1
 
    return count
 
# Driver Code
A = ["geekolymic", "google", "amazon"]
B = ["go"]
N = len(A)
M = len(B)
print(countcommon(A, B, N, M))


C#




using System;
using System.Collections.Generic;
 
class GFG
{
    static int CountCommon(List<string> A, List<string> B, int N, int M)
    {
        int[] freqB = new int[26];
        foreach (string curr in B)
        {
            foreach (char c in curr)
            {
                freqB++;
            }
        }
        int count = 0;
        foreach (string curr in A)
        {
            int[] freqA = new int[26];
            foreach (char c in curr)
            {
                freqA++;
            }
            bool flag = true;
            for (int j = 0; j < 26; j++)
            {
                if (freqB[j] != 0 && freqA[j] < freqB[j])
                {
                    flag = false;
                    break;
                }
            }
            if (flag)
            {
                count++;
            }
        }
        return count;
    }
 
    static void Main(string[] args)
    {
        List<string> A = new List<string> { "geekolymic", "google", "amazon" };
        List<string> B = new List<string> { "go" };
        int N = A.Count;
        int M = B.Count;
        Console.WriteLine(CountCommon(A, B, N, M));
    }
}


Javascript




function countcommon(A, B, N, M) {
  let freqB = new Array(26).fill(0);
  for (let i = 0; i < M; i++) {
    let curr = B[i];
    for (let j = 0; j < curr.length; j++) {
      freqB[curr.charCodeAt(j) - 97]++;
    }
  }
  let count = 0;
  for (let i = 0; i < N; i++) {
    let freqA = new Array(26).fill(0);
    let curr = A[i];
    for (let j = 0; j < curr.length; j++) {
      freqA[curr.charCodeAt(j) - 97]++;
    }
    let flag = true;
    for (let j = 0; j < 26; j++) {
      if (freqB[j] !== 0 && freqA[j] < freqB[j]) {
        flag = false;
        break;
      }
    }
    if (flag) {
      count++;
    }
  }
  return count;
}
 
// Driver Code
let A = ["geekolymic", "google", "amazon"];
let B = ["go"];
let N = A.length;
let M = B.length;
console.log(countcommon(A, B, N, M));


Output

2

Time Complexity: O(N)

Auxiliary Space: O(1)



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads