Given an array of strings arr[] and Q queries where each each query consists of a string str, the task is to find the longest string in the array that matches with prefix of the given string str i.e. the string must be prefix of str.
Examples:
Input: arr[] = {“GeeksForGeeks”, “GeeksForGeeksd”, “Arnab”, “Art”},
q[] = {“GeeksForGeeks”, “Ar”, “Art”}
Output:
GeeksForGeeks
-1
ArtInput: arr[] = {“Geek”, “Geek”, “Geekss”, “Geekk”},
q[] = {“Geek”, “Geeks”, “Geekk”, “Gee”}
Output:
Geek
-1
Geekk
-1
Naive approach: For every given string traverse through the array and check for the string which matches with prefix of the given string and store and print the longest string.
Efficient Approach: This problem can be solved using a Trie. We will form an trie and insert the strings of the array in the trie and find the longest string that completely matches with the prefix of the given string.
Below is the implementation of the above approach:
// C++ implementation of the approach #include <bits/stdc++.h> using namespace std;
const int ALPHABET_SIZE = 26;
// Trie node struct TrieNode {
struct TrieNode* children[ALPHABET_SIZE];
// isEndOfWord is true if the node represents
// end of a word
bool isEndOfWord;
}; // Returns new trie node (initialized to NULLs) struct TrieNode* getNode( void )
{ struct TrieNode* pNode = new TrieNode;
pNode->isEndOfWord = false ;
for ( int i = 0; i < ALPHABET_SIZE; i++)
pNode->children[i] = NULL;
return pNode;
} // If not present, inserts key into trie // If the key is prefix of trie node, just // marks leaf node void insert( struct TrieNode* root, string key)
{ struct TrieNode* pCrawl = root;
for ( int i = 0; i < key.length(); i++) {
int index = key[i] - 'a' ;
if (!pCrawl->children[index])
pCrawl->children[index] = getNode();
if (i == key.length() - 1)
// Mark last node as leaf
pCrawl->children[index]->isEndOfWord = true ;
pCrawl = pCrawl->children[index];
}
} string getString( char x)
{ // string class has a constructor
// that allows us to specify size of
// string as first parameter and character
// to be filled in given size as second
// parameter.
string s(1, x);
return s;
} // Function to return the // longest required string string search( struct TrieNode* root, string key)
{ struct TrieNode* pCrawl = root;
// Prefix of the string
string s = "" ;
for ( int i = 0; i < key.length(); i++) {
int index = key[i] - 'a' ;
if (!pCrawl->children[index])
break ;
s += getString(( char )key[i]);
pCrawl = pCrawl->children[index];
}
if (pCrawl->isEndOfWord)
return s;
return "-1" ;
} // Driver code int main()
{ string arr[] = { "Geeks" , "Geek" ,
"Geekss" , "Geekks" };
int n = sizeof (arr) / sizeof (string);
// Construct trie
struct TrieNode* root = getNode();
for ( int i = 0; i < n; i++)
insert(root, arr[i]);
string queries[] = { "Geek" , "Geeks" , "Geekk" , "Gee" };
int q = sizeof (queries) / sizeof (string);
for ( int i = 0; i < q; i++)
cout << search(root, queries[i]) << endl;
return 0;
} |
Geek Geeks -1 -1