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 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
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
Python - Count all prefixes in given string with greatest frequency Counting all prefixes in a given string with the greatest frequency involves identifying substrings that start from the beginning of the string and determining which appears most frequently. Using a Dictionary (DefaultDict)This approach uses defaultdict from the collections module to store prefix co
3 min read
Search a string in the dictionary with a given prefix and suffix for Q queries Given an array arr[] consisting of N strings and Q queries in form of two strings prefix and suffix, the task for each query is to find any one string in the given array with the given prefix and suffix. If there exists no such string then print "-1". Examples: Input: arr[] = {"apple", "app", "biscu
15+ min read
Queries to count distinct Binary Strings of all lengths from N to M satisfying given properties Given a K and a matrix Q[][] consisting of queries of the form {N, M}, the task for each query is to count the number of strings possible of all lengths from Q[i][0] to Q[i][1] satisfying the following properties: The frequency of 0's is equal to a multiple of K.Two strings are said to be different
6 min read
Length of all prefixes that are also the suffixes of given string Given a string S consisting of N characters, the task is to find the length of all prefixes of the given string S that are also suffixes of the same string S. Examples: Input: S = "ababababab"Output: 2 4 6 8Explanation: The prefixes of S that are also its suffixes are: "ab" of length = 2"abab" of le
10 min read