先决条件:特里
给定一个字符串str []列表和一个前缀字符串pre 。任务是使用trie计算具有给定前缀的字符串列表中的单词数。
例子:
Input: str = [ “apk”, “app”, “apple”, “arp”, “array” ], pre = “ap”
Output: 3
Explanation:
Below is the representation of trie from using above string.
The words in str having prefix “ap” are apk, app and apple.
So, the count is 3
Input: str = [ “gee”, “geek”, “geezer”, “geeksforgeeks”, “geekiness”, “geekgod” ], pre = “geek”
Output: 4
方法:
为了解决此问题,使用了Trie数据结构,并且该Trie的每个节点包含以下三个字段:
- children :此字段用于从字符映射到下一级Trie节点
- isEndOfWord :此字段用于将节点区分为单词节点的结尾
- 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中插入的最长单词的长度。