📌  相关文章
📜  使用Trie计算具有给定前缀的单词数

📅  最后修改于: 2021-04-17 09:49:46             🧑  作者: Mango

先决条件:特里

给定一个字符串str []列表和一个前缀字符串pre 。任务是使用trie计算具有给定前缀的字符串列表中的单词数。

例子:

方法:
为了解决此问题,使用了Trie数据结构,并且该Trie的每个节点包含以下三个字段:

  1. children :此字段用于从字符映射到下一级Trie节点
  2. isEndOfWord :此字段用于将节点区分为单词节点的结尾
  3. num :此字段用于计算在插入trie期间访问节点的次数

脚步:

  • 在trie中插入字符串列表,以使列表中的每个字符串都作为一个单独的trie节点插入。
  • 在插入更新期间,在trie的每个节点中的所有字段
  • 对于给定的前缀,遍历trie直到我们到达给定前缀pre的最后一个字符。
  • 字符串pre的最后一个节点中num字段的值是给定字符串列表中前缀的计数。

下面是上述方法的实现:

C++14
// C++ implementation of counting the
// number of words in a trie with a
// given prefix
#include "bits/stdc++.h"
using namespace std;
 
// Trie Node
struct TrieNode {
 
    // Using map to store the pointers
    // of children nodes for dynamic
    // implementation, for making the
    // program space efiicient
    map children;
 
    // If isEndOfWord is true, then
    // node represents end of word
    bool isEndOfWord;
 
    // num represents number of times
    // a character has appeared during
    // insertion of the words in the
    // trie
    map num;
};
 
// Declare root node
struct TrieNode* root;
 
// Function to create New Trie Node
struct TrieNode* getNewTrieNode()
{
    struct TrieNode* pNode = new TrieNode;
    pNode->isEndOfWord = false;
    return pNode;
}
 
// Function to insert a string in trie
void insertWord(string word)
{
    // To hold the value of root
    struct TrieNode* current = root;
 
    // To hold letters of the word
    char s;
 
    // Traverse through strings in list
    for (int i = 0; i < word.length(); i++) {
        s = word[i];
 
        // If s is not present in the
        // character field of current node
        if (current->children.find(s)
            == current->children.end()) {
 
            // Get new node
            struct TrieNode* p = getNewTrieNode();
 
            // Insert s in character
            // field of current node
            // with reference to node p
            (current->children)[s] = p;
 
            // Insert s in num field
            // of current node with
            // value 1
            (current->num)[s] = 1;
        }
        else {
 
            // Increment the count
            // corressponding to the
            // character s
            current->num[s] = (current->num)[s] + 1;
        }
 
        // Go to next node
        current = (current->children)[s];
    }
    current->isEndOfWord = true;
}
 
// Function to count the number of
// words in trie with given prefix
int countWords(vector& words,
               string prefix)
{
    root = getNewTrieNode();
 
    // Size of list of string
    int n = words.size();
 
    // Construct trie containing
    // all the words
    for (int i = 0; i < n; i++) {
        insertWord(words[i]);
    }
 
    struct TrieNode* current = root;
    char s;
 
    // Initialize the wordCount = 0
    int wordCount = 0;
 
    for (int i = 0; prefix[i]; i++) {
        s = prefix[i];
 
        // If the complete prefix is
        // not present in the trie
        if (current->children.find(s)
            == current->children.end()) {
 
            // Make wordCount 0 and
            // break out of loop
            wordCount = 0;
            break;
        }
 
        // Update the wordCount
        wordCount = (current->num)[s];
 
        // Go to next node
        current = (current->children)[s];
    }
 
    return wordCount;
}
 
// Driver Code
int main()
{
    // input list of words
    vector words;
    words = { "apk", "app", "apple",
              "arp", "array" };
 
    // Given prefix to find
    string prefix = "ap";
 
    // Print the number of words with
    // given prefix
    cout << countWords(words, prefix);
    return 0;
}


Python3
# Python3 implementation of counting the
# number of words in a trie with a
# given prefix
  
# Trie Node
class TrieNode:
     
    def __init__(self):
         
        # Using map to store the pointers
        # of children nodes for dynamic
        # implementation, for making the
        # program space efiicient
        self.children = dict()
     
        # If isEndOfWord is true, then
        # node represents end of word
        self.isEndOfWord = False
     
        # num represents number of times
        # a character has appeared during
        # insertion of the words in the
        # trie
        self.num = dict()
 
# Declare root node
root = None
 
# Function to create New Trie Node
def getNewTrieNode():
     
    pNode = TrieNode()
    return pNode
  
# Function to insert a string in trie
def insertWord(word):
     
    global root
     
    # To hold the value of root
    current = root
  
    # To hold letters of the word
    s = ''
  
    # Traverse through strings in list
    for i in range(len(word)):
        s = word[i]
  
        # If s is not present in the
        # character field of current node
        if (s not in current.children):
  
            # Get new node
            p = getNewTrieNode()
             
            # Insert s in character
            # field of current node
            # with reference to node p
            current.children[s] = p
  
            # Insert s in num field
            # of current node with
            # value 1
            current.num[s] = 1
        else:
  
            # Increment the count
            # corressponding to the
            # character s
            current.num[s] = current.num[s] + 1
  
        # Go to next node
        current = current.children[s]
     
    current.isEndOfWord = True
 
# Function to count the number of
# words in trie with given prefix
def countWords(words, prefix):
     
    global root
    root = getNewTrieNode()
  
    # Size of list of string
    n = len(words)
  
    # Construct trie containing
    # all the words
    for i in range(n):
        insertWord(words[i])
         
    current = root
    s = ''
  
    # Initialize the wordCount = 0
    wordCount = 0
     
    for i in range(len(prefix)):
        s = prefix[i]
  
        # If the complete prefix is
        # not present in the trie
        if (s not in current.children):
  
            # Make wordCount 0 and
            # break out of loop
            wordCount = 0
            break
         
        # Update the wordCount
        wordCount = (current.num)[s]
  
        # Go to next node
        current = (current.children)[s]
  
    return wordCount
 
# Driver Code
if __name__=='__main__':
     
    # input list of words
    words = [ "apk", "app", "apple",
              "arp", "array" ]
  
    # Given prefix to find
    prefix = "ap"
  
    # Print the number of words with
    # given prefix
    print(countWords(words, prefix))
     
# This code is contributed by rutvik_56


输出:
3

时间复杂度:O(n * l) ,其中n =在Trie中插入的单词数,l =在Trie中插入的最长单词的长度。