Count of strings whose prefix match with the given string to a given length k

23 May, 2022
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 prefix 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++
Java
Python3
C#
Javascript
// C++ implementation of the approach#include <bits/stdc++.h>using namespace std; // Trie node (considering only lowercase alphabets)struct Node {    Node* arr[26];    int freq;}; // Function to insert a node in the trieNode* insert(string s, Node* root){    int in;    Node* cur = root;    for (int i = 0; i < s.length(); i++) {        in = s[i] - 'a';         // If there is no node created then create one        if (cur->arr[in] == NULL)            cur->arr[in] = new Node();         // Increase the frequency of the node        cur->arr[in]->freq++;         // Move to the next node        cur = cur->arr[in];    }     // Return the updated root    return root;} // Function to return the count of strings// whose prefix of length k matches with the// k length prefix of the given stringint find(string s, int k, Node* root){    int in, count = 0;    Node* cur = root;     // Traverse the string    for (int i = 0; i < s.length(); i++) {        in = s[i] - 'a';         // If there is no node then return 0        if (cur->arr[in] == NULL)            return 0;         // Else traverse to the required node        cur = cur->arr[in];         count++;         // Return the required count        if (count == k)            return cur->freq;    }    return 0;} // Driver codeint main(){    string arr[] = { "abba", "abbb", "abbc", "abbd", "abaa", "abca" };    int n = sizeof(arr) / sizeof(string);     Node* root = new Node();     // Insert the strings in the trie    for (int i = 0; i < n; i++)        root = insert(arr[i], root);     // Query 1    cout << find("abbg", 3, root) << endl;     // Query 2    cout << find("abg", 2, root) << endl;     // Query 3    cout << find("xyz", 2, root) << endl;     return 0;}
// Java implementation of the approachclass GFG{     // Trie node (considering only lowercase alphabets)    static class Node    {        Node[] arr = new Node[26];        int freq;    };     // Function to insert a node in the trie    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 there is no node created then create one            if (cur.arr[in] == null)                cur.arr[in] = new Node();             // Increase the frequency of the node            cur.arr[in].freq++;             // Move to the next node            cur = cur.arr[in];        }         // Return the updated root        return root;    }     // Function to return the count of Strings    // whose prefix of length k matches with the    // k length prefix of the given String    static int find(String s, int k, Node root)    {        int in, count = 0;        Node cur = root;         // Traverse the String        for (int i = 0; i < s.length(); i++)        {            in = s.charAt(i) - 'a';             // If there is no node then return 0            if (cur.arr[in] == null)                return 0;             // Else traverse to the required node            cur = cur.arr[in];             count++;             // Return the required count            if (count == k)                return cur.freq;        }        return 0;    }     // Driver code    public static void main(String[] args)    {        String arr[] = { "abba", "abbb", "abbc",                        "abbd", "abaa", "abca" };        int n = arr.length;         Node root = new Node();         // Insert the Strings in the trie        for (int i = 0; i < n; i++)            root = insert(arr[i], root);         // Query 1        System.out.print(find("abbg", 3, root) + "\n");         // Query 2        System.out.print(find("abg", 2, root) + "\n");         // Query 3        System.out.print(find("xyz", 2, root) + "\n");     }} // This code is contributed by PrinciRaj1992
# Python3 implementation of the approach # Trie node (considering only lowercase alphabets)class Node :    def __init__(self):        self.arr = [None]*26        self.freq = 0     class Trie:         # Trie data structure class    def __init__(self):        self.root = self.getNode()     def getNode(self):             # Returns new trie node (initialized to NULLs)        return Node()     # Function to insert a node in the trie    def insert(self, s):                 _in = 0        cur = self.root        for i in range(len(s)):            _in = ord(s[i]) - ord('a')             # If there is no node created then create one            if not cur.arr[_in]:                cur.arr[_in] = self.getNode()             # Increase the frequency of the node            cur.arr[_in].freq += 1             # Move to the next node            cur = cur.arr[_in]     # Function to return the count of strings    # whose prefix of length k matches with the    # k length prefix of the given string    def find(self, s, k):                 _in = 0        count = 0        cur = self.root         # Traverse the string        for i in range(len(s)):            _in = ord(s[i]) - ord('a')             # If there is no node then return 0            if cur.arr[_in] == None:                return 0             # Else traverse to the required node            cur = cur.arr[_in]             count += 1             # Return the required count            if count == k:                return cur.freq        return 0 # Driver codedef main():         arr = [ "abba", "abbb", "abbc", "abbd", "abaa", "abca" ]    n = len(arr)     root = Trie();     # Insert the strings in the trie    for i in range(n):        root.insert(arr[i])     # Query 1    print(root.find("abbg", 3))     # Query 2    print(root.find("abg", 2))     # Query 3    print(root.find("xyz", 2)) if __name__ == '__main__':    main()     # This code is contributed by divyamohan123    
// C# implementation of the approachusing System; class GFG{     // Trie node (considering only lowercase alphabets)    public class Node    {        public Node[] arr = new Node[26];        public int freq;    };     // Function to insert a node in the trie    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 there is no node created then create one            if (cur.arr[iN] == null)                cur.arr[iN] = new Node();             // Increase the frequency of the node            cur.arr[iN].freq++;             // Move to the next node            cur = cur.arr[iN];        }         // Return the updated root        return root;    }     // Function to return the count of Strings    // whose prefix of length k matches with the    // k length prefix of the given String    static int find(String s, int k, Node root)    {        int iN, count = 0;        Node cur = root;         // Traverse the String        for (int i = 0; i < s.Length; i++)        {            iN = s[i] - 'a';             // If there is no node then return 0            if (cur.arr[iN] == null)                return 0;             // Else traverse to the required node            cur = cur.arr[iN];             count++;             // Return the required count            if (count == k)                return cur.freq;        }        return 0;    }     // Driver code    public static void Main(String[] args)    {        String []arr = { "abba", "abbb", "abbc",                        "abbd", "abaa", "abca" };        int n = arr.Length;         Node root = new Node();         // Insert the Strings in the trie        for (int i = 0; i < n; i++)            root = insert(arr[i], root);         // Query 1        Console.Write(find("abbg", 3, root) + "\n");         // Query 2        Console.Write(find("abg", 2, root) + "\n");         // Query 3        Console.Write(find("xyz", 2, root) + "\n");     }} // This code is contributed by 29AjayKumar
<script> // JavaScript implementation of the approach // Trie node (considering only lowercase alphabets)class Node{    constructor()    {        this.arr=new Array(26);        this.freq=0;    }} // Function to insert a node in the triefunction 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 there is no node created then create one            if (cur.arr[In] == null)                cur.arr[In] = new Node();               // Increase the frequency of the node            cur.arr[In].freq++;               // Move to the next node            cur = cur.arr[In];        }           // Return the updated root        return root;} // Function to return the count of Strings    // whose prefix of length k matches with the    // k length prefix of the given Stringfunction find(s,k,root){    let In, count = 0;        let cur = root;           // Traverse the String        for (let i = 0; i < s.length; i++)        {            In = s[i].charCodeAt(0) - 'a'.charCodeAt(0);               // If there is no node then return 0            if (cur.arr[In] == null)                return 0;               // Else traverse to the required node            cur = cur.arr[In];               count++;               // Return the required count            if (count == k)                return cur.freq;        }        return 0;} // Driver codelet arr=["abba", "abbb", "abbc",                        "abbd", "abaa", "abca"];let n = arr.length; let root = new Node(); // Insert the Strings in the triefor (let i = 0; i < n; i++)    root = insert(arr[i], root); // Query 1document.write(find("abbg", 3, root) + "<br>"); // Query 2document.write(find("abg", 2, root) + "<br>"); // Query 3document.write(find("xyz", 2, root) + "<br>");  // This code is contributed by rag2127 </script>
4
6
0
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++
Java
Python3
#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); // storing k-length substring of str        int count            = 0; // counter to count the matching condition         // looping through each word of arr        for (int i = 0; i < n; i++) {            if (arr[i].length()                < k) // if the length of string from arr is                     // less than k                continue; // then there is no point in                          // finding the substring so we                          // skip            string b = arr[i].substr(                0, k); // storing k-length substring of each                       // string from arr            if (a == b) // checking equality of the two                        // substring a and b                count++; // if condition matches increase                         // the counter        }         return count; // finally return the 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;}
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); // storing k-length substring of str        int count            = 0; // counter to count the matching condition         // looping through each word of arr        for (int i = 0; i < n; i++) {            if (arr[i].length()                < k) // if the length of string from arr is                     // less than k                continue; // then there is no point in                          // finding the substring so we                          // skip             String b = arr[i].substring(                0, k); // storing k-length substring of each                       // string from arr            if (a.equals(b)) // checking equality of the two                             // substring a and b                count++; // if condition matches increase                         // the counter        }         return count; // finally return the count    }}
class Solution:    def klengthpref(self, arr, n, k, s):        a = s[:k]  # storing k-length substring of str        count = 0  # counter to count the matching condition         # looping through each word of arr        for i in range(n):            if(len(arr[i]) < k):  # if the length of string from arr is less than k                continue  # then there is no point in finding the substring so we skip            t = arr[i]            b = t[:k]  # storing k-length substring of each string from arr            if(a == b):  # checking equality of the two substring a and b                count += 1  # if condition matches increase the counter by 1        return count  # finally return the count  arr = ["abba", "abbb", "abbc", "abbd", "abaa", "abca"]str = "abbg"n = len(arr)k = 3 obj = Solution()print(obj.klengthpref(arr, n, k, str))
4
princiraj1992
29AjayKumar
divyamohan123
rag2127
sandeepkrsuman
prefix
Trie
Advanced Data Structure
Competitive Programming
Trie
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Decision Tree Introduction with example
Binary Indexed Tree or Fenwick Tree
AVL Tree | Set 2 (Deletion)
Disjoint Set Data Structures
Difference between B tree and B+ tree
Competitive Programming - A Complete Guide
Practice for cracking any coding interview
Arrow operator -> in C/C++ with Examples
Modulo 10^9+7 (1000000007)
Prefix Sum Array - Implementation and Applications in Competitive Programming