Skip to content
Related Articles

Related Articles

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

Improve Article
Save Article
  • Difficulty Level : Hard
  • Last Updated : 29 Nov, 2022
Improve Article
Save Article

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

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 <bits/stdc++.h>
using namespace std;
 
// Trie Node
struct Trie {
    Trie* arr[27] = { 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<vector<string> > 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][0];
        string suffix = Q[i][1];
        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<vector<string> > Q = { { "a", "e" }, { "mi", "ne" } };
    findMatchingString(arr, N, Q);
 
    return 0;
}


Java




// Java program for the above approach
import java.io.*;
import java.util.*;
 
class GFG {
 
  // Trie Node
  public static class Trie {
 
    Trie []arr = new Trie[27];
 
    // Stores the index of the word
    // in the dictionary
    int idx;
  };
 
  // Root node of the Trie
  public static Trie root;
 
  // Function to insert the words in
  // the Trie
  public static 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 (int ch=0; ch < word.length(); ch++){
 
      // Make a Trie Node, if not
      // already present
      if (temp.arr[word.charAt(ch) - 'a'] == null) {
        Trie t = new Trie();
        temp.arr[word.charAt(ch) - 'a'] = t;
      }
 
      temp = temp.arr[word.charAt(ch) - 'a'];
      temp.idx = i;
    }
  }
 
  // Function to search the words in Trie
  public static int search(String word)
  {
    Trie temp = root;
 
    // Traverse through all the
    // characters of current word
    for (int ch=0; ch < word.length(); ch++) {
 
      // If no valid Trie Node exists
      // for the current character
      // then there is no match
      if (temp.arr[word.charAt(ch) - 'a'] == null)
        return -1;
      temp = temp.arr[word.charAt(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
  public static void findMatchingString(
    String[] words, int n,
    String[][] 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].length() - 1;
           j >= 0; j--) {
        t = words[i].charAt(j) + temp;
        temp = t;
 
        // Insert into Trie
        insert(t, i);
      }
    }
 
    // Traverse all the queries
    for (int i = 0; i < Q.length ; i++) {
 
      String prefix = Q[i][0];
      String suffix = Q[i][1];
      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) {
        System.out.println(words[res]);
      }
 
      // Otherwise, No match found
      else
        System.out.println("-1");
    }
  }
 
  public static void main (String[] args) {
    String[] arr
      = { "apple", "app", "biscuit",
         "mouse", "orange", "bat",
         "microphone", "mine" };
    int N = 8;
    root=new Trie();
    String[][] Q = { { "a", "e" }, { "mi", "ne" } };
    findMatchingString(arr, N, Q);
  }
}
 
// This code is contributed by Aman Kumar.


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
Related Articles

Start Your Coding Journey Now!