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++
// 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 trie 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 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 int 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
// Java implementation of the approach class 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
# 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 code def 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#
// C# implementation of the approach using 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 |
4 6 0