Count of strings whose prefix match with the given string to a given length k
Last Updated :
29 Aug, 2023
Given an array of strings arr[] and given some queries where each query consists of a string str and an integer k. The task is to find the count of strings in arr[] whose prefix of length k matches with the k length prefix of str.
Examples:
Input: arr[] = {“abba”, “abbb”, “abbc”, “abbd”, “abaa”, “abca”}, str = “abbg”, k = 3
Output: 4
“abba”, “abbb”, “abbc” and “abbd” are the matching strings.
Input: arr[] = {“geeks”, “geeksforgeeks”, “forgeeks”}, str = “geeks”, k = 2
Output: 2
Prerequisite: Trie | (Insert and Search)
Approach: We will form a trie and insert all the strings in the trie and we will create another variable (frequency) for each node which will store the frequency of prefixes of the given strings. Now to get the count of strings whose prefix matches with the given string to a given length k we will have to traverse the trie to the length k from the root, the frequency of the Node will give the count of such strings.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
struct Node {
Node* arr[26];
int freq;
};
Node* insert(string s, Node* root)
{
int in;
Node* cur = root;
for ( int i = 0; i < s.length(); i++) {
in = s[i] - 'a' ;
if (cur->arr[in] == NULL)
cur->arr[in] = new Node();
cur->arr[in]->freq++;
cur = cur->arr[in];
}
return root;
}
int find(string s, int k, Node* root)
{
int in, count = 0;
Node* cur = root;
for ( int i = 0; i < s.length(); i++) {
in = s[i] - 'a' ;
if (cur->arr[in] == NULL)
return 0;
cur = cur->arr[in];
count++;
if (count == k)
return cur->freq;
}
return 0;
}
int main()
{
string arr[] = { "abba" , "abbb" , "abbc" , "abbd" , "abaa" , "abca" };
int n = sizeof (arr) / sizeof (string);
Node* root = new Node();
for ( int i = 0; i < n; i++)
root = insert(arr[i], root);
cout << find( "abbg" , 3, root) << endl;
cout << find( "abg" , 2, root) << endl;
cout << find( "xyz" , 2, root) << endl;
return 0;
}
|
Java
class GFG
{
static class Node
{
Node[] arr = new Node[ 26 ];
int freq;
};
static Node insert(String s, Node root)
{
int in;
Node cur = root;
for ( int i = 0 ; i < s.length(); i++)
{
in = s.charAt(i) - 'a' ;
if (cur.arr[in] == null )
cur.arr[in] = new Node();
cur.arr[in].freq++;
cur = cur.arr[in];
}
return root;
}
static int find(String s, int k, Node root)
{
int in, count = 0 ;
Node cur = root;
for ( int i = 0 ; i < s.length(); i++)
{
in = s.charAt(i) - 'a' ;
if (cur.arr[in] == null )
return 0 ;
cur = cur.arr[in];
count++;
if (count == k)
return cur.freq;
}
return 0 ;
}
public static void main(String[] args)
{
String arr[] = { "abba" , "abbb" , "abbc" ,
"abbd" , "abaa" , "abca" };
int n = arr.length;
Node root = new Node();
for ( int i = 0 ; i < n; i++)
root = insert(arr[i], root);
System.out.print(find( "abbg" , 3 , root) + "\n" );
System.out.print(find( "abg" , 2 , root) + "\n" );
System.out.print(find( "xyz" , 2 , root) + "\n" );
}
}
|
Python3
class Node :
def __init__( self ):
self .arr = [ None ] * 26
self .freq = 0
class Trie:
def __init__( self ):
self .root = self .getNode()
def getNode( self ):
return Node()
def insert( self , s):
_in = 0
cur = self .root
for i in range ( len (s)):
_in = ord (s[i]) - ord ( 'a' )
if not cur.arr[_in]:
cur.arr[_in] = self .getNode()
cur.arr[_in].freq + = 1
cur = cur.arr[_in]
def find( self , s, k):
_in = 0
count = 0
cur = self .root
for i in range ( len (s)):
_in = ord (s[i]) - ord ( 'a' )
if cur.arr[_in] = = None :
return 0
cur = cur.arr[_in]
count + = 1
if count = = k:
return cur.freq
return 0
def main():
arr = [ "abba" , "abbb" , "abbc" , "abbd" , "abaa" , "abca" ]
n = len (arr)
root = Trie();
for i in range (n):
root.insert(arr[i])
print (root.find( "abbg" , 3 ))
print (root.find( "abg" , 2 ))
print (root.find( "xyz" , 2 ))
if __name__ = = '__main__' :
main()
|
C#
using System;
class GFG
{
public class Node
{
public Node[] arr = new Node[26];
public int freq;
};
static Node insert(String s, Node root)
{
int iN;
Node cur = root;
for ( int i = 0; i < s.Length; i++)
{
iN = s[i] - 'a' ;
if (cur.arr[iN] == null )
cur.arr[iN] = new Node();
cur.arr[iN].freq++;
cur = cur.arr[iN];
}
return root;
}
static int find(String s, int k, Node root)
{
int iN, count = 0;
Node cur = root;
for ( int i = 0; i < s.Length; i++)
{
iN = s[i] - 'a' ;
if (cur.arr[iN] == null )
return 0;
cur = cur.arr[iN];
count++;
if (count == k)
return cur.freq;
}
return 0;
}
public static void Main(String[] args)
{
String []arr = { "abba" , "abbb" , "abbc" ,
"abbd" , "abaa" , "abca" };
int n = arr.Length;
Node root = new Node();
for ( int i = 0; i < n; i++)
root = insert(arr[i], root);
Console.Write(find( "abbg" , 3, root) + "\n" );
Console.Write(find( "abg" , 2, root) + "\n" );
Console.Write(find( "xyz" , 2, root) + "\n" );
}
}
|
Javascript
<script>
class Node
{
constructor()
{
this .arr= new Array(26);
this .freq=0;
}
}
function insert(s,root)
{
let In;
let cur = root;
for (let i = 0; i < s.length; i++)
{
In = s[i].charCodeAt(0) - 'a' .charCodeAt(0);
if (cur.arr[In] == null )
cur.arr[In] = new Node();
cur.arr[In].freq++;
cur = cur.arr[In];
}
return root;
}
function find(s,k,root)
{
let In, count = 0;
let cur = root;
for (let i = 0; i < s.length; i++)
{
In = s[i].charCodeAt(0) - 'a' .charCodeAt(0);
if (cur.arr[In] == null )
return 0;
cur = cur.arr[In];
count++;
if (count == k)
return cur.freq;
}
return 0;
}
let arr=[ "abba" , "abbb" , "abbc" ,
"abbd" , "abaa" , "abca" ];
let n = arr.length;
let root = new Node();
for (let i = 0; i < n; i++)
root = insert(arr[i], root);
document.write(find( "abbg" , 3, root) + "<br>" );
document.write(find( "abg" , 2, root) + "<br>" );
document.write(find( "xyz" , 2, root) + "<br>" );
</script>
|
Time Complexity: O(N*M), where N is the size of the array and M is the maximum length of string present in that array.
Auxiliary Space: O(N*M)
Approach without using Trie:
The idea is to use substring of length k. Since we are dealing with prefixes we need to consider the substring of length k starting from index 0. This substring will always be the prefix of the string. Store the k-length substring of str from index 0 in a string a. Run a loop for each word in the string array and for each word which is of length greater than k take the substring of length k starting from index 0. Now check for equality of the two substrings a and b. If the two are equal increase the count. Finally after coming out of the loop return the count.
C++
#include <bits/stdc++.h>
using namespace std;
class Solution {
public :
int klengthpref(string arr[], int n, int k, string str)
{
string a = str.substr(
0, k);
int count
= 0;
for ( int i = 0; i < n; i++) {
if (arr[i].length()
< k)
continue ;
string b = arr[i].substr(
0, k);
if (a == b)
count++;
}
return count;
}
};
int main()
{
string arr[] = { "abba" , "abbb" , "abbc" ,
"abbd" , "abaa" , "abca" };
string str = "abbg" ;
int n = sizeof (arr) / sizeof (string), k = 3;
Solution ob;
cout << ob.klengthpref(arr, n, k, str);
return 0;
}
|
Java
class GFG {
public static void main(String args[])
{
String[] arr = { "abba" , "abbb" , "abbc" ,
"abbd" , "abaa" , "abca" };
String str = "abbg" ;
int n = arr.length, k = 3 ;
Solution obj = new Solution();
int ans = obj.klengthpref(arr, n, k, str);
System.out.println(ans);
}
}
class Solution {
public int klengthpref(String[] arr, int n, int k,
String str)
{
String a = str.substring(
0 , k);
int count
= 0 ;
for ( int i = 0 ; i < n; i++) {
if (arr[i].length()
< k)
continue ;
String b = arr[i].substring(
0 , k);
if (a.equals(b))
count++;
}
return count;
}
}
|
Python3
class Solution:
def klengthpref( self , arr, n, k, s):
a = s[:k]
count = 0
for i in range (n):
if ( len (arr[i]) < k):
continue
t = arr[i]
b = t[:k]
if (a = = b):
count + = 1
return count
arr = [ "abba" , "abbb" , "abbc" , "abbd" , "abaa" , "abca" ]
str = "abbg"
n = len (arr)
k = 3
obj = Solution()
print (obj.klengthpref(arr, n, k, str ))
|
C#
using System;
class GFG {
static void Main( string [] args) {
string [] arr = { "abba" , "abbb" , "abbc" , "abbd" , "abaa" , "abca" };
string str = "abbg" ;
int n = arr.Length;
int k = 3;
Solution obj = new Solution();
int ans = obj.Klengthpref(arr, n, k, str);
Console.WriteLine(ans);
}
}
class Solution {
public int Klengthpref( string [] arr, int n, int k, string str) {
string a = str.Substring(0, k);
int count = 0;
for ( int i = 0; i < n; i++) {
if (arr[i].Length < k)
continue ;
string b = arr[i].Substring(0, k);
if (a.Equals(b))
count++;
}
return count;
}
}
|
Javascript
<script>
class Solution {
klengthpref(arr, n, k, str) {
let a = str.substr(0, k);
let count = 0;
for (let i = 0; i < n; i++) {
if (arr[i].length < k) {
continue ;
}
let b = arr[i].substr(0, k);
if (a == b) {
count++;
}
}
return count;
}
}
let arr = [ "abba" , "abbb" , "abbc" , "abbd" , "abaa" , "abca" ];
let str = "abbg" ;
let n = arr.length;
let k = 3;
let ob = new Solution();
document.write(ob.klengthpref(arr, n, k, str));
</script>
|
Time Complexity: O(N*M), where N is the size of the array and M is the maximum length of string present in that array.
Auxiliary Space: O(M)
Approach Name: Prefix Match Count
Steps:
- Initialize a variable count to 0 to keep track of the number of strings in arr[] that match the prefix of length k in str.
- Loop through all the strings in arr[].
- Check if the prefix of length k in the current string matches the prefix of length k in str.
- If it does, increment the count variable.
- Return the count variable as the result of the query.
C++
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int PrefixMatchCount(vector<string>& arr, string str, int k) {
int count = 0;
for ( const string& s : arr) {
if (s.substr(0, k) == str.substr(0, k)) {
count++;
}
}
return count;
}
int main() {
vector<string> arr = { "abba" , "abbb" , "abbc" , "abbd" , "abaa" , "abca" };
string str = "abbg" ;
int k = 3;
cout << PrefixMatchCount(arr, str, k) << endl;
return 0;
}
|
Java
import java.io.*;
class GFG {
public static int prefixMatchCount(String[] arr,
String str, int k)
{
int count = 0 ;
for (String s : arr) {
if (s.substring( 0 , k).equals(
str.substring( 0 , k))) {
count++;
}
}
return count;
}
public static void main(String[] args)
{
String[] arr = { "abba" , "abbb" , "abbc" ,
"abbd" , "abaa" , "abca" };
String str = "abbg" ;
int k = 3 ;
System.out.println(prefixMatchCount(arr, str, k));
}
}
|
Python3
def prefixMatchCount(arr, str , k):
count = 0
for s in arr:
if s[:k] = = str [:k]:
count + = 1
return count
arr = [ "abba" , "abbb" , "abbc" , "abbd" , "abaa" , "abca" ]
str = "abbg"
k = 3
print (prefixMatchCount(arr, str , k))
|
C#
using System;
class Program
{
static int PrefixMatchCount( string [] arr, string str, int k)
{
int count = 0;
foreach ( string s in arr)
{
if (s.Substring(0, k) == str.Substring(0, k))
{
count++;
}
}
return count;
}
static void Main( string [] args)
{
string [] arr = { "abba" , "abbb" , "abbc" , "abbd" , "abaa" , "abca" };
string str = "abbg" ;
int k = 3;
Console.WriteLine(PrefixMatchCount(arr, str, k));
}
}
|
Javascript
function prefixMatchCount(arr, str, k) {
let count = 0;
for (let s of arr) {
if (s.substring(0, k) === str.substring(0, k)) {
count++;
}
}
return count;
}
let arr = [ "abba" , "abbb" , "abbc" , "abbd" , "abaa" , "abca" ];
let str = "abbg" ;
let k = 3;
console.log(prefixMatchCount(arr, str, k));
|
Time Complexity: O(N*L), where N is the number of strings in arr[] and L is the maximum length of a string in arr[] and str.
Auxiliary Space: O(1)
Share your thoughts in the comments
Please Login to comment...