Number of strings in two array satisfy the given conditions

Given two arrays of string arr1[] and arr2[]. For each string in arr2[](say str2), the task is to count numbers string in arr1[](say str1) which satisfy the below conditions:

  • The first characters of str1 and str2 must be equal.
  • String str2 must contains each characters of string str1.

Examples:

Input: arr1[] = {“aaaa”, “asas”, “able”, “ability”, “actt”, “actor”, “access”}, arr2[] = {“aboveyz”, “abrodyz”, “abslute”, “absoryz”, “actresz”, “gaswxyz”}
Output:
1
1
3
2
4
0
Explanation:
Following are the string in arr1[] which follows the given condition:
1 valid word for “aboveyz” : “aaaa”.
1 valid word for “abrodyz” : “aaaa”.
3 valid words for “abslute” : “aaaa”, “asas”, “able”.
2 valid words for “absoryz” : “aaaa”, “asas”.
4 valid words for “actresz” : “aaaa”, “asas”, “actt”, “access”.
There’re no valid words for “gaswxyz” cause none of the words in the list contains letter ‘g’.
Input: arr1[] = {“abbg”, “able”, “abslute”, “abil”, “actresz”, “gaswxyz”}, arr2[] = {“abbgaaa”, “asas”, “able”, “ability”}
Output:
1
0
1
1

Approach: This problem can be solved using the concept of Bitmasking. Below are the steps:

  1. Convert each string of the array arr1[] to it’s corresponding bitmask as shown below:
    For string str = "abcd"
    the corresponding bitmask conversion is:
    characters | value 
        a          0
        b          1
        c          2
        d          3
    As per the above characters value, the number is:
    value = 20 + 21 + 23 + 24
    value = 15.
    so the string "abcd" represented as 15.
    

    Note: While bitmasking each string if the frequency of characters is more than 1, then include that corresponding characters only once.

  2. Store the frequency of each string in an unordered_map.
  3. Similarly, convert each string in the arr2[] to the corresponding bitmask and do the following:
    • Instead of calculating all possible words corresponding to arr1[], use bit operation to find the next valid bitmask using temp = (temp – 1)&val.
    • It produces the next bitmask pattern reducing one char at a time by producing all possible combinations.
  4. For each valid permutation check if it validate the given two condition and add corresponding frequency to the current string stored in unordered_map to the result.

Below is the implementation of the above approach:



filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
  
void findNumOfValidWords(vector<string>& w,
                         vector<string>& p)
{
    // To store the frequency of string
    // after bitmasking
    unordered_map<int, int> m;
  
    // To store result for each string
    // in arr2[]
    vector<int> res;
  
    // Traverse the arr1[] and bitmask each
    // string in it
    for (string& s : w) {
  
        int val = 0;
  
        // Bitmasking for each string s
        for (char c : s) {
            val = val | (1 << (c - 'a'));
        }
  
        // Update the frequency of string
        // with it's bitmasking value
        m[val]++;
    }
  
    // Traverse the arr2[]
    for (string& s : p) {
        int val = 0;
  
        // Bitmasking for each string s
        for (char c : s) {
            val = val | (1 << (c - 'a'));
        }
  
        int temp = val;
        int first = s[0] - 'a';
        int count = 0;
  
        while (temp != 0) {
  
            // Check if temp is present
            // in an unordered_map or not
            if (((temp >> first) & 1) == 1) {
                if (m.find(temp) != m.end()) {
                    count += m[temp];
                }
            }
  
            // Check for next set bit
            temp = (temp - 1) & val;
        }
  
        // Push the count for current
        // string in resultant array
        res.push_back(count);
    }
  
    // Print the count for each string
    for (auto& it : res) {
        cout << it << '\n';
    }
}
  
// Driver Code
int main()
{
    vector<string> arr1;
    arr1 = { "aaaa", "asas", "able",
             "ability", "actt",
             "actor", "access" };
  
    vector<string> arr2;
    arr2 = { "aboveyz", "abrodyz",
             "abslute", "absoryz",
             "actresz", "gaswxyz" };
  
    // Function call
    findNumOfValidWords(arr1, arr2);
    return 0;
}

chevron_right


Output:

1
1
3
2
4
0


Time Complexity: O(N)
Space Complexity: O(N)

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.




My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.