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 contain each character of string str1.
Examples:
Input: arr1[] = {“aaaa”, “asas”, “able”, “ability”, “actt”, “actor”, “access”}, arr2[] = {“aboveyz”, “abrodyz”, “absolute”, “absoryz”, “actresz”, “gaswxyz”}
Output:
1
1
3
2
4
0
Explanation:
The following is 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 “absolute” : “aaaa”, “asas”, “able”.
2 valid words for “absoryz” : “aaaa”, “asas”.
4 valid words for “actresz” : “aaaa”, “asas”, “actt”, “access”.
There are no valid words for “gaswxyz” because none of the words in the list contains the letter ‘g’.
Input: arr1[] = {“abbg”, “able”, “absolute”, “abil”, “actresz”, “gaswxyz”}, arr2[] = {“abbgaaa”, “asas”, “able”, “ability”}
Output:
1
0
1
1
Brute Force Approach: This approach uses a nested loop to iterate through each string in arr1 and arr2, and checks if the first character of each string in arr1 matches the first character of the string in arr2.
Step by step algorithm:
- Initialize an empty vector of integers called result to store the count of valid strings.
- For each string str2 in arr2, do the following:
a. Initialize a counter variable called count to 0.
b. For each string str1 in arr1, do the following:
i. Check if the first character of str1 is equal to the first character of str2.
ii. If they are equal, iterate over each character c in str1, and check if it is present in str2 using the find() function.
iii. If all characters of str1 are present in str2, increment the count.
c. Add the final count to the result vector.
- Return the result vector.
Below is the implementation of above approach:
C++
#include <iostream>
#include <vector>
#include <string>
using namespace std;
vector< int > count_strings(vector<string> arr1, vector<string> arr2) {
vector< int > result;
for (string str2 : arr2) {
int count = 0;
for (string str1 : arr1) {
if (str1[0] == str2[0]) {
bool flag = true ;
for ( char c : str1) {
if (str2.find(c) == string::npos) {
flag = false ;
break ;
}
}
if (flag) {
count++;
}
}
}
result.push_back(count);
}
return result;
}
int main() {
vector<string> arr1 = { "aaaa" , "asas" , "able" , "ability" , "actt" , "actor" , "access" };
vector<string> arr2 = { "aboveyz" , "abrodyz" , "absolute" , "absoryz" , "actresz" , "gaswxyz" };
vector< int > result = count_strings(arr1, arr2);
for ( int i : result) {
cout << i << "\n" ;
}
return 0;
}
|
Java
import java.util.ArrayList;
import java.util.List;
public class StringCounter {
public static List<Integer>
countStrings(List<String> arr1, List<String> arr2)
{
List<Integer> result
= new ArrayList<>();
for (String str2 :
arr2) {
int count = 0 ;
for (String str1 :
arr1) {
if (str1.charAt( 0 )
== str2.charAt(
0 )) {
boolean flag = true ;
for ( char c :
str1.toCharArray()) {
if (str2.indexOf(c)
== - 1 ) {
flag = false ;
break ;
}
}
if (flag) {
count++;
}
}
}
result.add(
count);
}
return result;
}
public static void main(String[] args)
{
List<String> arr1
= List.of( "aaaa" , "asas" , "able" , "ability" ,
"actt" , "actor" , "access" );
List<String> arr2
= List.of( "aboveyz" , "abrodyz" , "absolute" ,
"absoryz" , "actresz" , "gaswxyz" );
List<Integer> result = countStrings(arr1, arr2);
for ( int i : result) {
System.out.println(i);
}
}
}
|
Python3
def count_strings(arr1, arr2):
result = []
for str2 in arr2:
count = 0
for str1 in arr1:
if str1[ 0 ] = = str2[ 0 ]:
flag = True
for c in str1:
if c not in str2:
flag = False
break
if flag:
count + = 1
result.append(count)
return result
if __name__ = = '__main__' :
arr1 = [ "aaaa" , "asas" , "able" , "ability" , "actt" , "actor" , "access" ]
arr2 = [ "aboveyz" , "abrodyz" , "absolute" , "absoryz" , "actresz" , "gaswxyz" ]
result = count_strings(arr1, arr2)
for i in result:
print (i)
|
C#
using System;
using System.Collections.Generic;
class GFG
{
static List< int > CountStrings(List< string > arr1, List< string > arr2)
{
List< int > result = new List< int >();
foreach ( string str2 in arr2)
{
int count = 0;
foreach ( string str1 in arr1)
{
if (str1[0] == str2[0])
{
bool flag = true ;
foreach ( char c in str1)
{
if (str2.IndexOf(c) == -1)
{
flag = false ;
break ;
}
}
if (flag)
{
count++;
}
}
}
result.Add(count);
}
return result;
}
static void Main()
{
List< string > arr1 = new List< string > { "aaaa" , "asas" , "able" , "ability" , "actt" , "actor" , "access" };
List< string > arr2 = new List< string > { "aboveyz" , "abrodyz" , "absolute" , "absoryz" , "actresz" , "gaswxyz" };
List< int > result = CountStrings(arr1, arr2);
foreach ( int i in result)
{
Console.WriteLine(i);
}
}
}
|
Javascript
function countStrings(arr1, arr2) {
const result = [];
for (const str2 of arr2) {
let count = 0;
for (const str1 of arr1) {
if (str1[0] === str2[0]) {
let flag = true ;
for (const c of str1) {
if (str2.indexOf(c) === -1) {
flag = false ;
break ;
}
}
if (flag) {
count++;
}
}
}
result.push(count);
}
return result;
}
function main() {
const arr1 = [ "aaaa" , "asas" , "able" , "ability" , "actt" , "actor" , "access" ];
const arr2 = [ "aboveyz" , "abrodyz" , "absolute" , "absoryz" , "actresz" , "gaswxyz" ];
const result = countStrings(arr1, arr2);
for (const i of result) {
console.log(i);
}
}
main();
|
Time Complexity: O(N^2)
Space Complexity: O(1)
Approach: This problem can be solved using the concept of Bitmasking. Below are the steps:
- Convert each string of the array arr1[] to its 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 the corresponding characters only once.
- Store the frequency of each string in an unordered_map.
- 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 the 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.
- For each valid permutation, check if it validates the given two conditions and adds the corresponding frequency to the current string stored in an unordered_map to the result.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
void findNumOfValidWords(vector<string>& w,
vector<string>& p)
{
unordered_map< int , int > m;
vector< int > res;
for (string& s : w) {
int val = 0;
for ( char c : s) {
val = val | (1 << (c - 'a' ));
}
m[val]++;
}
for (string& s : p) {
int val = 0;
for ( char c : s) {
val = val | (1 << (c - 'a' ));
}
int temp = val;
int first = s[0] - 'a' ;
int count = 0;
while (temp != 0) {
if (((temp >> first) & 1) == 1) {
if (m.find(temp) != m.end()) {
count += m[temp];
}
}
temp = (temp - 1) & val;
}
res.push_back(count);
}
for ( auto & it : res) {
cout << it << '\n' ;
}
}
int main()
{
vector<string> arr1;
arr1 = { "aaaa" , "asas" , "able" ,
"ability" , "actt" ,
"actor" , "access" };
vector<string> arr2;
arr2 = { "aboveyz" , "abrodyz" ,
"absolute" , "absoryz" ,
"actresz" , "gaswxyz" };
findNumOfValidWords(arr1, arr2);
return 0;
}
|
Java
import java.util.*;
class GFG{
static void findNumOfValidWords(Vector<String> w,
Vector<String> p)
{
HashMap<Integer,
Integer> m = new HashMap<>();
Vector<Integer> res = new Vector<>();
for (String s : w)
{
int val = 0 ;
for ( char c : s.toCharArray())
{
val = val | ( 1 << (c - 'a' ));
}
if (m.containsKey(val))
m.put(val, m.get(val) + 1 );
else
m.put(val, 1 );
}
for (String s : p)
{
int val = 0 ;
for ( char c : s.toCharArray())
{
val = val | ( 1 << (c - 'a' ));
}
int temp = val;
int first = s.charAt( 0 ) - 'a' ;
int count = 0 ;
while (temp != 0 )
{
if (((temp >> first) & 1 ) == 1 )
{
if (m.containsKey(temp))
{
count += m.get(temp);
}
}
temp = (temp - 1 ) & val;
}
res.add(count);
}
for ( int it : res)
{
System.out.println(it);
}
}
public static void main(String[] args)
{
Vector<String> arr1 = new Vector<>();
arr1.add( "aaaa" ); arr1.add( "asas" );
arr1.add( "able" ); arr1.add( "ability" );
arr1.add( "actt" ); arr1.add( "actor" );
arr1.add( "access" );
Vector<String> arr2 = new Vector<>();
arr2.add( "aboveyz" ); arr2.add( "abrodyz" );
arr2.add( "absolute" ); arr2.add( "absoryz" );
arr2.add( "actresz" ); arr2.add( "gaswxyz" );
findNumOfValidWords(arr1, arr2);
}
}
|
Python3
from collections import defaultdict
def findNumOfValidWords(w, p):
m = defaultdict( int )
res = []
for s in w:
val = 0
for c in s:
val = val | ( 1 << ( ord (c) - ord ( 'a' )))
m[val] + = 1
for s in p:
val = 0
for c in s:
val = val | ( 1 << ( ord (c) - ord ( 'a' )))
temp = val
first = ord (s[ 0 ]) - ord ( 'a' )
count = 0
while (temp ! = 0 ):
if (((temp >> first) & 1 ) = = 1 ):
if (temp in m):
count + = m[temp]
temp = (temp - 1 ) & val
res.append(count)
for it in res:
print (it)
if __name__ = = "__main__" :
arr1 = [ "aaaa" , "asas" , "able" ,
"ability" , "actt" ,
"actor" , "access" ]
arr2 = [ "aboveyz" , "abrodyz" ,
"absolute" , "absoryz" ,
"actresz" , "gaswxyz" ]
findNumOfValidWords(arr1, arr2)
|
C#
using System;
using System.Collections.Generic;
class GFG{
static void findNumOfValidWords(List<String> w,
List<String> p)
{
Dictionary< int ,
int > m = new Dictionary< int ,
int >();
List< int > res = new List< int >();
foreach (String s in w)
{
int val = 0;
foreach ( char c in s.ToCharArray())
{
val = val | (1 << (c - 'a' ));
}
if (m.ContainsKey(val))
m[val] = m[val] + 1;
else
m.Add(val, 1);
}
foreach (String s in p)
{
int val = 0;
foreach ( char c in s.ToCharArray())
{
val = val | (1 << (c - 'a' ));
}
int temp = val;
int first = s[0] - 'a' ;
int count = 0;
while (temp != 0)
{
if (((temp >> first) & 1) == 1)
{
if (m.ContainsKey(temp))
{
count += m[temp];
}
}
temp = (temp - 1) & val;
}
res.Add(count);
}
foreach ( int it in res)
{
Console.WriteLine(it);
}
}
public static void Main(String[] args)
{
List<String> arr1 = new List<String>();
arr1.Add( "aaaa" ); arr1.Add( "asas" );
arr1.Add( "able" ); arr1.Add( "ability" );
arr1.Add( "actt" ); arr1.Add( "actor" );
arr1.Add( "access" );
List<String> arr2 = new List<String>();
arr2.Add( "aboveyz" ); arr2.Add( "abrodyz" );
arr2.Add( "absolute" ); arr2.Add( "absoryz" );
arr2.Add( "actresz" ); arr2.Add( "gaswxyz" );
findNumOfValidWords(arr1, arr2);
}
}
|
Javascript
<script>
function findNumOfValidWords(w, p)
{
var m = new Map();
var res = [];
w.forEach(s => {
var val = 0;
s.split( '' ).forEach(c => {
val = val | (1 << (c.charCodeAt(0) - 'a' .charCodeAt(0)));
});
if (m.has(val))
m.set(val, m.get(val)+1)
else
m.set(val, 1)
});
p.forEach(s => {
var val = 0;
s.split(' ').forEach(c => {
val = val | (1 << (c.charCodeAt(0) - ' a '.charCodeAt(0)));
});
var temp = val;
var first = s[0].charCodeAt(0) - ' a'.charCodeAt(0);
var count = 0;
while (temp != 0) {
if (((temp >> first) & 1) == 1) {
if (m.has(temp)) {
count += m.get(temp);
}
}
temp = (temp - 1) & val;
}
res.push(count);
});
res.forEach(it => {
document.write( it + "<br>" );
});
}
var arr1 = [ "aaaa" , "asas" , "able" ,
"ability" , "actt" ,
"actor" , "access" ];
var arr2 = [ "aboveyz" , "abrodyz" ,
"absolute" , "absoryz" ,
"actresz" , "gaswxyz" ];
findNumOfValidWords(arr1, arr2);
</script>
|
Time Complexity: O(N)
Space Complexity: O(N)
Feeling lost in the world of random DSA topics, wasting time without progress? It's time for a change! Join our DSA course, where we'll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 geeks!