📌  相关文章
📜  在字典中搜索具有给定前缀和后缀的字符串以进行 Q 查询

📅  最后修改于: 2022-05-13 01:57:07.844000             🧑  作者: Mango

在字典中搜索具有给定前缀和后缀的字符串以进行 Q 查询

给定一个由N个字符串和Q个查询组成的数组arr[] ,形式为两个字符串prefixsuffix ,每个查询的任务是在给定数组中找到具有给定prefixsuffix的任何一个字符串。如果不存在这样的字符串,则打印“-1”

例子:

朴素方法:解决给定问题的最简单方法是遍历每个查询的给定字符串数组arr[] ,如果存在具有给定前缀和后缀的任何此类字符串,则打印该字符串。否则,打印“-1”

时间复杂度: O(Q*N*M),其中 M 是字符串的最大长度
辅助空间: O(1)

高效方法:上述方法也可以通过使用 Trie 数据结构来解决问题进行优化。可以通过以下方式修改 trie 的实现以支持前缀和后缀搜索:

  • 假设字典中的给定单词是apple 。在这种情况下,单词apple被插入到 Trie 中。但要支持前缀和后缀同时搜索的话: e{apple, le{apple, ple{apple, pple{apple, apple{apple可以插入到Trie中。
  • 请注意,这些单词的形式为suffix{word ,其中suffix是给定单词的所有可能的后缀。
  • 特殊字符{插入在后缀和单词之间以分隔它们。可以使用除字母表之外的任何特殊字符来代替{ ,但首选{ ,因为它的 ASCII 值是 123,比z的 ASCII 值大一。

请按照以下步骤解决问题:

  • 使用变量i遍历数组arr[]中的所有字符串,并执行以下步骤:
    • 初始化一个字符串 , temp'{' + arr[i]
    • 遍历字符串中的所有字符,从末尾arr[i]开始,将每个字符附加到字符串temp的前面,然后将此字符串插入到 trie 中。
  • 创建 trie 后,遍历所有查询并执行以下步骤:
    • 存储当前查询的前缀后缀字符串。
    • 初始化一个字符串, t后缀+'{'+前缀,在trie中搜索。
    • 如果找不到,则打印“-1” 。否则,打印匹配的字符串。

下面是上述方法的实现:

C++
// C++ program for the above approach
  
#include 
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 > 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 > Q = { { "a", "e" }, { "mi", "ne" } };
    findMatchingString(arr, N, Q);
  
    return 0;
}


输出:
apple
mine

时间复杂度: O(N*M 2 + Q*M),其中M是所有字符串中的最大长度
辅助空间: O(N*M 2 )