# Search a string in the dictionary with a given prefix and suffix for Q queries

• Difficulty Level : Hard
• Last Updated : 10 Jul, 2021

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”, “biscuit”, “mouse”, “orange”, “bat”, “microphone”, “mine”}, Queries[] = {{a, e}, {a, p}}
Output:
apple
app
Explanation:
Query 1: String “apple” is the only word in the given dictionary with the given prefix “a” and suffix “e”.
Query 2: String “app” is the only word in the given dictionary with the given prefix “a” and suffix “p”.

Input: arr[] = {“apple”, “app”, “biscuit”, “mouse”, “orange”, “bat”, “microphone”, “mine”}, Queries[] = {{mi, ne}}
Output: mine

## Recommended: Please try your approach on {IDE} first, before moving on to the solution.

Naive Approach: The simplest approach to solve the given problem is to traverse the given array of strings arr[] for each query and if there exists any such string with the given prefix and suffix, then print that string. Otherwise, print “-1”.

Time Complexity: O(Q*N*M), where M is the maximum length of the string.
Auxiliary Space: O(1)

Efficient Approach: The above approach can also be optimized by using the Trie Data Structure to solve the problem. The implementation of trie can be modified to support both prefix and suffix search in the following way:

• Suppose the given word in a dictionary is apple. In this case, the word apple is inserted in the Trie. But to support prefix and suffix search simultaneously the words: e{apple, le{apple, ple{apple, pple{apple, apple{apple can be inserted in the Trie.
• Note that these words are of the form suffix{word where suffix is the all suffixes possible from the given word.
• The special character { is inserted between the suffix and word to separate them. Any special character other than the alphabets can be used in place of {, but { is preferred because its ASCII value is 123 which is one more than the ASCII value of z.

Follow the steps below to solve the problem:

Below is the implementation of the above approach:

## C++

 `// C++ program for the above approach`` ` `#include ``using` `namespace` `std;`` ` `// Trie Node``struct` `Trie {``    ``Trie* arr = { NULL };`` ` `    ``// Stores the index of the word``    ``// in the dictionary``    ``int` `idx;``};`` ` `// Root node of the Trie``Trie* root = ``new` `Trie();`` ` `// Function to insert the words in``// the Trie``void` `insert(string word, ``int` `i)``{``    ``// Temporary pointer to the root``    ``// node of the Trie``    ``Trie* temp = root;`` ` `    ``// Traverse through all the``    ``// characters of current word``    ``for` `(``char` `ch : word) {`` ` `        ``// Make a Trie Node, if not``        ``// already present``        ``if` `(temp->arr[ch - ``'a'``] == NULL) {``            ``Trie* t = ``new` `Trie();``            ``temp->arr[ch - ``'a'``] = t;``        ``}`` ` `        ``temp = temp->arr[ch - ``'a'``];``        ``temp->idx = i;``    ``}``}`` ` `// Function to search the words in Trie``int` `search(string word)``{``    ``Trie* temp = root;`` ` `    ``// Traverse through all the``    ``// characters of current word``    ``for` `(``char` `ch : word) {`` ` `        ``// If no valid Trie Node exists``        ``// for the current character``        ``// then there is no match``        ``if` `(temp->arr[ch - ``'a'``] == NULL)``            ``return` `-1;``        ``temp = temp->arr[ch - ``'a'``];``    ``}`` ` `    ``// Return the resultant index``    ``return` `temp->idx;``}`` ` `// Function to search for a word in``// the dictionary with the given``// prefix and suffix for each query``void` `findMatchingString(``    ``string words[], ``int` `n,``    ``vector > Q)``{``    ``string temp, t;`` ` `    ``// Insertion in the Trie``    ``for` `(``int` `i = 0; i < n; i++) {`` ` `        ``// Form all the words of the``        ``// form suffix{word and insert``        ``// them in the trie``        ``temp = ``"{"` `+ words[i];`` ` `        ``for` `(``int` `j = words[i].size() - 1;``             ``j >= 0; j--) {``            ``t = words[i][j] + temp;``            ``temp = t;`` ` `            ``// Insert into Trie``            ``insert(t, i);``        ``}``    ``}`` ` `    ``// Traverse all the queries``    ``for` `(``int` `i = 0; i < Q.size(); i++) {`` ` `        ``string prefix = Q[i];``        ``string suffix = Q[i];``        ``string temp = suffix + ``"{"` `+ prefix;`` ` `        ``// Stores the index of``        ``// the required word``        ``int` `res;`` ` `        ``// Store the index of the``        ``// word in the dictionary``        ``res = search(temp);`` ` `        ``// In case of match, print``        ``// the corresponding string``        ``if` `(res != -1) {``            ``cout << words[res] << ``'\n'``;``        ``}`` ` `        ``// Otherwise, No match found``        ``else``            ``cout << ``"-1\n"``;``    ``}``}`` ` `// Driver Code``int` `main()``{``    ``string arr[]``        ``= { ``"apple"``, ``"app"``, ``"biscuit"``,``            ``"mouse"``, ``"orange"``, ``"bat"``,``            ``"microphone"``, ``"mine"` `};``    ``int` `N = 8;``    ``vector > Q = { { ``"a"``, ``"e"` `}, { ``"mi"``, ``"ne"` `} };``    ``findMatchingString(arr, N, Q);`` ` `    ``return` `0;``}`

Output:

```apple
mine
```

Time Complexity: O(N*M2 + Q*M), where M is the maximum length of among all the strings
Auxiliary Space: O(N*M2)

My Personal Notes arrow_drop_up