Count of Strings of Array having given prefixes for Q query
Last Updated :
30 Jan, 2023
Given two arrays of strings containing words[] and queries[] having N and Q strings respectively, the task is to find the number of strings from words[] having queries[i] as the prefix for all the strings in queries[].
Examples:
Input: words[] = { "geeks", "geeks", "geeks for geeks", "string", "strong" }, queries[] = { "geek", "gel", "str" }
Output: 3, 0, 2
Explanation:
1st query "geek" is present in 3 words in the list as a prefix, { "geekf", "geeks", "geeksforgeeks" }
2nd query "gel" is not present in any word in the list as a prefix
3rd query "str" is present in 2 words in the list as a prefix, {"string", "strong"}
Input: words[] = { "apple", "app", "ape", "alien", "a", "box", "boxing" }, queries[] = { "a", "ap", "b", "app", "book" }
Output: 5, 3, 2, 2, 0
Explanation:
1st query "a" is present in 5 words in the list as a prefix, { "apple", "app", "ape", "alien", "a" }
2nd query "ap" is present in 3 words in the list as a prefix, { "apple", "app", "ape" }
3rd query "b" is present in 2 words in the list as a prefix, {"box", "boxing"}
4th query "app" is present in 2 words in the list as a prefix, {"apple", "app"}
5th query "book" is not present in any word in the list as a prefix
Naive Approach: The problem can be solved based on the following idea:
For each query traverse through every word in the list and check whether the word has a prefix as current query or not.
- Create a dummy vector ans, to store the resultant array.
- Start traversing queries[] and initialize a counter variable count to store the count of words that have prefixes as the current query.
- If the size of any word at any ith iteration is less than the size of the query, skip the iteration.
- If the prefix is found in words[] then increment the counter variable.
- Push count of prefixes in the vector ans.
- Return the ans.
Below is the implementation of the above approach.
C++
// C++ code to implement the approach
#include <bits/stdc++.h>
using namespace std;
// Function to return an array containing
// the number of words having the given prefix
// for each query
vector<int> GeekAndString(vector<string>& words,
vector<string>& Queries)
{
vector<int> ans;
for (string x : Queries) {
// To count number of
// matching prefixes in word array
int count = 0;
for (string word : words) {
if (word.size() < x.size())
continue;
// If prefix found then increment counter
if (word.substr(0, x.size()) == x)
count++;
}
ans.push_back(count);
}
return ans;
}
// Driver Code
int main()
{
vector<string> words
= { "geekf", "geeks", "geeksforgeeks",
"string", "strong" };
vector<string> queries = { "geek", "gel", "str" };
// Function call
vector<int> ans = GeekAndString(words, queries);
for (int x : ans)
cout << x << " ";
return 0;
}
Java
// Java code to implement the approach
import java.util.*;
class GFG {
// Driver Code
public static void main(String[] args)
{
String[] words = { "geekf", "geeks", "geeksforgeeks",
"string", "strong" };
String[] queries = { "geek", "gel", "str" };
// Function call
ArrayList<Integer> ans
= GeekAndString(words, queries);
for (int count : ans) {
System.out.print(count + " ");
}
System.out.println();
}
// Function to return an array
// containing the number of words
// having given prefix for each query
public static ArrayList<Integer>
GeekAndString(String[] Li, String[] Queries)
{
ArrayList<Integer> answer = new ArrayList<>();
for (String x : Queries) {
int count = 0;
for (String word : Li) {
if (word.length() < x.length())
continue;
if (x.equals(
word.substring(0, x.length()))) {
count++;
}
}
answer.add(count);
}
return answer;
}
}
Python3
# Python3 code to implement the approach
# Function to return an array containing
# the number of words having the given prefix
# for each query
def GeekAndString(words, Queries) :
ans = [];
for x in Queries :
# To count number of number of
# matching prefixes in word array
count = 0;
for word in words :
if len(word) < len(x) :
continue;
# If prefix found then increment counter
if (word[0 : len(x)] == x) :
count += 1;
ans.append(count);
return ans;
# Driver Code
if __name__ == "__main__" :
words = [ "geekf", "geeks", "geeksforgeeks","string", "strong" ];
queries = [ "geek", "gel", "str" ];
# Function call
ans = GeekAndString(words, queries);
for x in ans:
print(x,end=" ");
# This code is contributed by AnkThon
C#
// C# code to implement the approach
using System;
using System.Collections;
class GFG {
// Driver Code
public static void Main(string[] args)
{
string[] words
= { "geekf", "geeks", "geeksforgeeks", "string",
"strong" };
string[] queries = { "geek", "gel", "str" };
// Function call
ArrayList ans = GeekAndString(words, queries);
foreach(int count in ans)
{
Console.Write(count + " ");
}
Console.WriteLine();
}
// Function to return an array
// containing the number of words
// having given prefix for each query
public static ArrayList GeekAndString(string[] Li,
string[] Queries)
{
ArrayList answer = new ArrayList();
foreach(string x in Queries)
{
int count = 0;
foreach(string word in Li)
{
if (word.Length < x.Length)
continue;
if (x.Equals(word.Substring(0, x.Length))) {
count++;
}
}
answer.Add(count);
}
return answer;
}
}
// This code is contributed by Samim Hossain Mondal.
JavaScript
// JavaScript code to implement the approach
// Function to return an array containing
// the number of words having the given prefix
// for each query
const GeekAndString = (words, Queries) => {
let ans = [];
for (let x in Queries) {
// To count number of number of
// matching prefixes in word array
let count = 0;
for (let word in words) {
if (words[word].length < Queries[x].length)
continue;
// If prefix found then increment counter
if (words[word].substring(0, Queries[x].length) == Queries[x])
count++;
}
ans.push(count);
}
return ans;
}
// Driver Code
let words = ["geekf", "geeks", "geeksforgeeks", "string", "strong"];
let queries = ["geek", "gel", "str"];
// Function call
let ans = GeekAndString(words, queries);
for (let x in ans)
console.log(`${ans[x]} `);
// This code is contributed by rakeshsahni
Time Complexity: O(N * Q * M), where M = maximum length of a string in queries[]
Auxiliary Space: O(N)
Efficient approach: The problem can be solved efficiently on the basis of the following approach
We have to use such a data structure to match the string to find out if it is prefix of another string in optimal time. Trie can help us in this problem.
Build a trie and insert the strings of word[] in the trie. where each node will also keep a count of strings with that prefix. Then while traversing through queries[] find the prefix and the count associated with it. The structure of a trie node will be like the following:
- children: This field is used for mapping from a character to the next level trie node
- isEndOfWord: This field is used to distinguish the node as end of word node
- num: This field is used to count the number of times a node is visited during insertion in trie
Follow the steps mentioned below to implement the idea:
- Insert the list of strings in trie such that every string in the list is inserted as an individual trie node.
- During inserting update all the fields in every node of the trie
- For each query, traverse the trie till we reach the last character of the given prefix queries[i].
- The value of the num field in the last node of the prefix is the count of strings of words[] having the given prefix.
- For each query, store this num, in an answer vector.
Below is the implementation of the above approach:
C++
// C++ code to implement the approach
#include <bits/stdc++.h>
using namespace std;
int x;
// Structure of a trie node
struct trie {
int cnt;
trie* ch[26];
trie()
{
cnt = 0;
for (int i = 0; i < 26; i++)
ch[i] = NULL;
}
};
// Function to build the trie
void build(vector<string>& a, trie* root)
{
trie* temp;
for (int i = 0; i < x; i++) {
temp = root;
for (int j = 0; j < a[i].size(); j++) {
if (temp->ch[a[i][j] - 'a'] == NULL)
temp->ch[a[i][j] - 'a'] = new trie();
temp->ch[a[i][j] - 'a']->cnt += 1;
temp = temp->ch[a[i][j] - 'a'];
}
}
}
// Function to find a string in the trie
int find(string s, trie* root)
{
for (int i = 0; i < s.size(); i++) {
if (root->ch[s[i] - 'a'] == NULL)
return 0;
root = root->ch[s[i] - 'a'];
}
return root->cnt;
}
// Function to get the given number of string
// having the same prefix as the query
vector<int> prefixCount(int N, int Q,
vector<string>& list,
vector<string>& query)
{
vector<int> res;
x = N;
trie* root = new trie();
build(list, root);
for (int i = 0; i < Q; i++)
res.push_back(find(query[i], root));
return res;
}
// Driver Code
int main()
{
vector<string> words
= { "geekf", "geeks", "geeksforgeeks",
"string", "strong" };
vector<string> queries = { "geek", "gel", "str" };
// Function call
vector<int> ans = prefixCount(
words.size(), queries.size(), words, queries);
for (int count : ans)
cout << count << " ";
return 0;
}
Java
// Java code to implement the approach
import java.util.*;
class GFG {
// Driver Code
public static void main(String[] args)
{
String[] words
= { "geekf", "geeks", "geeksforgeeks",
"string", "strong" };
String[] queries = { "geek", "gel", "str" };
// Function call
ArrayList<Integer> ans
= GeekAndString(words, queries);
for (int count : ans)
System.out.print(count + " ");
}
// Function to get the given number of string
// having the same prefix as the query
public static ArrayList<Integer>
GeekAndString(String[] Li, String[] Queries)
{
ArrayList<Integer> answer = new ArrayList<>();
Trie trie = new Trie();
for (String word : Li) {
trie.inert(word);
}
for (String word : Queries) {
answer.add(trie.query(word));
}
return answer;
}
}
// Structure of a trie node
class TrieNode {
TrieNode[] links;
int counter;
TrieNode()
{
this.links = new TrieNode[26];
this.counter = 0;
}
}
// Structure of a trie
class Trie {
private TrieNode root;
Trie() { this.root = new TrieNode(); }
// Function to insert the string in the trie
public void inert(String word)
{
TrieNode node = root;
for (int i = 0; i < word.length(); i++) {
int pos = (word.charAt(i) - 'a');
if (node.links[pos] == null) {
node.links[pos] = new TrieNode();
}
node = node.links[pos];
node.counter = node.counter + 1;
}
}
// Function to find answer for each query
public int query(String word)
{
TrieNode node = root;
for (int i = 0; i < word.length(); i++) {
int pos = (word.charAt(i) - 'a');
if (node.links[pos] == null) {
return 0;
}
node = node.links[pos];
}
return node.counter;
}
}
Python
# Python code to implement the above approach
# Structure of a trie node
class Trie:
def __init__(self):
self.cnt = 0
self.ch = [None] * 26
# Function to build the trie
def build(a, root):
temp = None
for i in range(len(a)):
temp = root
for j in range(len(a[i])):
if not temp.ch[ord(a[i][j]) - ord('a')]:
temp.ch[ord(a[i][j]) - ord('a')] = Trie()
temp.ch[ord(a[i][j]) - ord('a')].cnt += 1
temp = temp.ch[ord(a[i][j]) - ord('a')]
# Function to find a string in the trie
def find(s, root):
for i in range(len(s)):
if not root.ch[ord(s[i]) - ord('a')]:
return 0
root = root.ch[ord(s[i]) - ord('a')]
return root.cnt
# Function to get the given number of string
# having the same prefix as the query
def prefixCount(N, Q, list, query):
res = []
root = Trie()
build(list, root)
for i in range(Q):
res.append(find(query[i], root))
return res
# Driver Code
words = ["geekf", "geeks", "geeksforgeeks","string", "strong"]
queries = ["geek", "gel", "str"]
# Function call
ans = prefixCount(len(words), len(queries), words, queries)
print(ans)
C#
// C# code to implement the approach
using System;
using System.Collections.Generic;
// Structure of a trie node
public class TrieNode {
public TrieNode[] links;
public int counter;
public TrieNode()
{
this.links = new TrieNode[26];
this.counter = 0;
}
}
// Structure of a trie
public class Trie {
private TrieNode root;
public Trie() { this.root = new TrieNode(); }
// Function to insert the string in the trie
public void Insert(string word)
{
TrieNode node = root;
for (int i = 0; i < word.Length; i++) {
int pos = (word[i] - 'a');
if (node.links[pos] == null) {
node.links[pos] = new TrieNode();
}
node = node.links[pos];
node.counter = node.counter + 1;
}
}
// Function to find answer for each query
public int Query(string word)
{
TrieNode node = root;
for (int i = 0; i < word.Length; i++) {
int pos = (word[i] - 'a');
if (node.links[pos] == null) {
return 0;
}
node = node.links[pos];
}
return node.counter;
}
}
public class GFG {
// Function to get the given number of string
// having the same prefix as the query
static List<int> GeekAndString(string[] Li,
string[] Queries)
{
List<int> answer = new List<int>();
Trie trie = new Trie();
foreach(string word in Li) { trie.Insert(word); }
foreach(string word in Queries)
{
answer.Add(trie.Query(word));
}
return answer;
}
static public void Main()
{
// Code
string[] words
= { "geekf", "geeks", "geeksforgeeks", "string",
"strong" };
string[] queries = { "geek", "gel", "str" };
// Function call
List<int> ans = GeekAndString(words, queries);
foreach(int count in ans)
Console.Write(count + " ");
}
}
// This code is contributed by lokeshmvs21.
JavaScript
// Javascript code to implement the approach
let x;
// Structure of a trie node
class trie {
constructor(){
this.cnt=0;
this.ch= new Array(26);
}
};
// Function to build the trie
function build( a, root)
{
let temp=new trie();
for (let i = 0; i < x; i++) {
temp = root;
for (let j = 0; j < a[i].length; j++) {
let x= a[i].charCodeAt(j)-97;
if (temp.ch[x] == null)
temp.ch[x] = new trie();
temp.ch[x].cnt += 1;
temp = temp.ch[x];
}
}
}
// Function to find a string in the trie
function find( s, root)
{
for (let i = 0; i < s.length; i++) {
let x= s.charCodeAt(i)-97;
if (root.ch[x] == null)
return 0;
root = root.ch[x];
}
return root.cnt;
}
// Function to get the given number of string
// having the same prefix as the query
function prefixCount(N, Q,list, query)
{
let res=[];
x = N;
let root = new trie();
build(list, root);
for (let i = 0; i < Q; i++)
res.push(find(query[i], root));
return res;
}
// Driver Code
let words
= [ "geekf", "geeks", "geeksforgeeks",
"string", "strong" ];
let queries = [ "geek", "gel", "str" ];
// Function call
let ans = prefixCount(
words.length, queries.length, words, queries);
console.log(ans);
// This code is contributed by garg28harsh.
Time Complexity: O(Q * x + N*L), Where x is the longest word in the query, and L = length of the longest word inserted in the trie.
Auxiliary Space: O(N * List [i])
Similar Reads
Count of Superstrings in a given array of strings
Given 2 array of strings X and Y, the task is to find the number of superstrings in X. A string s is said to be a Superstring, if each string present in array Y is a subsequence of string s . Examples: Input: X = {"ceo", "alco", "caaeio", "ceai"}, Y = {"ec", "oc", "ceo"}Output: 2Explanation: Strings
8 min read
Count of Isogram strings in given Array of Strings
Given an array arr[] containing N strings, the task is to find the count of strings which are isograms. A string is an isogram if no letter in that string appears more than once. Examples: Input: arr[] = {"abcd", "derg", "erty"}Output: 3Explanation: All given strings are isograms. In all the strings
5 min read
Count of Palindrome Strings in given Array of strings
Given an array of strings arr[] of size N where each string consists only of lowercase English letter. The task is to return the count of all palindromic string in the array. Examples: Input: arr[] = {"abc","car","ada","racecar","cool"}Output: 2Explanation: "ada" and "racecar" are the two palindrome
5 min read
Count of Perfect Numbers in given range for Q queries
Given an array arr[] consisting of N pairs, where each pair represents a query of the form {L, R}, the task is to find the count of perfect numbers in the given range for each query. Examples: Input: arr[][] = {{1, 10}, {10, 20}, {20, 30}}Output: 1 1 1Explanation: Query(1, 10): Perfect numbers in th
9 min read
Queries for counts of array values in a given range
Given an unsorted array of integers and a set of m queries, where each query consists of two integers x and y, the task is to determine the number of elements in the array that lie within the range [x, y] (inclusive) for each query.Examples: Input: arr = [1, 3, 4, 9, 10, 3], queries = [[1, 4], [9, 1
15+ min read
Count set bits in index range [L, R] in given Array for Q queries
Given an array arr[] containing N integers and an array queries[] containing Q queries in the form of {L, R}, the task is to count the total number of set bits from L to R in array arr for each query. Example: Input: arr[]={1, 2, 3, 4, 5, 6}, queries[]={{0, 2}, {1, 1}, {3, 5}}Output:425Explanation:Q
6 min read
Count triplets having product 0 from a given array
Given an array arr[] of size N, the task is to count the number of triplets (arr[i], arr[j], arr[k]) such that arr[i] * arr[j] = arr[j] * arr[k] = 0 (i < j < k). Examples: Input: arr[] = {0, 8, 12, 0} Output: 2 Explanation: Triplets satisfying the given conditions are (0, 8, 0) and (0, 12, 0).
8 min read
Count of possible remainders for K in given ranges for Q queries
Given an array arr[ ] which contains N positive integers and an integer K and a vector of queries Q . Two types of queries can be asked: In the type 1 query, all elements from index l to r are increased by value X. The input format of this query: 1 l r xIn the type 2 query, for a given integer K pri
15+ min read
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 contain each character of string str1.Examples: Input: a
14 min read
Count of N digit numbers not having given prefixes
Given an integer N and a vector of strings prefixes[], the task is to calculate the total possible strings of length N from characters '0' to '9'. such that the given prefixes cannot be used in any of the strings. Examples: Input: N = 3, prefixes = {"42"}Output: 990Explanation: All string except{"42
8 min read