先决条件: Trie | (插入和搜索)
给定的字符串话[]和一个局部字符串str数组,则任务是从字符串的给定阵列查找给定形式str的字符串。
A partial string is a string with some missing characters. For Example: “..ta”, is a string of length 4 ending with “ta” and having two missing character at index 0 and 1.
例子:
Input: words[] = [“moon”, “soon”, “month”, “date”, “data”], str = “..on”
Output: [“moon”, “soon”]
Explanation:
“moon” and “soon” matches the given partial string “..on”
Input: words[] = [“date”, “data”, “month”], str = “d.t.”
Output: [“date”, “data”]
Explanation:
“date” and “data” matches the given partial string “d.t.”
方法:
特里节点的结构:想法是使用特里来解决给定的问题以下是特里的步骤和结构:
struct TrieNode
{
struct TrieNode* children[26];
bool endOfWord;
};
下图说明了使用上面示例中给出的键构造trie
root
/ | \
d m s
| | |
a o o
| | \ |
t o n o
/ | | | |
e a n t n
|
h
每个节点都是一个TrieNode ,其指针根据添加的单词指向后续子代。不存在字符的其他指针位置的值用NULL标记。 endOfWord由蓝色或叶节点表示。
脚步:
- 使用addWord()方法将所有可用单词插入到trie结构中。
- 要添加的单词的每个字符都作为单独的TrieNode插入。 children数组是26个TrieNode指针的数组。
- 每个索引代表英文字母中的一个字符。如果添加了新单词,则对于每个字符,必须检查该字母的TrieNode指针是否存在,然后继续处理下一个字符,如果不存在,则创建一个新的TrieNode并使该指针指向该新节点并在此新节点上为下一个字符重复该过程。 endOfWord是由最后一个字符的TrieNode指针所指向的TrieNode发虚。
- 为了搜索键,检查在字符标记的索引处是否存在TrieNode。如果存在,我们将向下移动分支,并对下一个字符重复该过程。类似地,如果是‘。’,则搜索部分字符串。找到后,我们将在children数组中查找所有可用的TrieNode指针,然后进一步处理由索引标识的每个字符,其位置为“。”。一次。
- 如果指针位置在任何时候都为空,则返回找不到。在最后TrieNode为endOfWord否则检查,如有虚假,我们的回报没有找到,其他的字被发现。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Dictionary Class
class Dictionary {
public:
// Initialize your data structure
Dictionary* children[26];
bool endOfWord;
// Constructor
Dictionary()
{
this->endOfWord = false;
for (int i = 0; i < 26; i++) {
this->children[i] = NULL;
}
}
// Adds a word into a data structure
void addWord(string word)
{
// Crawl pointer points the object
// in reference
Dictionary* pCrawl = this;
// Traverse the given array of words
for (int i = 0; i < word.length(); i++) {
int index = word[i] - 'a';
if (!pCrawl->children[index])
pCrawl->children[index]
= new Dictionary();
pCrawl = pCrawl->children[index];
}
pCrawl->endOfWord = true;
}
// Function that returns if the word
// is in the data structure or not
// A word can contain a dot character '.'
// to represent any one letter
void search(string word, bool& found,
string curr_found = "",
int pos = 0)
{
Dictionary* pCrawl = this;
if (pos == word.length()) {
if (pCrawl->endOfWord) {
cout << "Found: "
<< curr_found << "\n";
found = true;
}
return;
}
if (word[pos] == '.') {
// Iterate over every letter and
// proceed further by replacing
// the character in place of '.'
for (int i = 0; i < 26; i++) {
if (pCrawl->children[i]) {
pCrawl
->children[i]
->search(word,
found,
curr_found + char('a' + i),
pos + 1);
}
}
}
else {
// Check if pointer at character
// position is available,
// then proceed
if (pCrawl->children[word[pos] - 'a']) {
pCrawl
->children[word[pos] - 'a']
->search(word,
found,
curr_found + word[pos],
pos + 1);
}
}
return;
}
// Utility function for search operation
void searchUtil(string word)
{
Dictionary* pCrawl = this;
cout << "\nSearching for \""
<< word << "\"\n";
bool found = false;
pCrawl->search(word, found);
if (!found)
cout << "No Word Found...!!\n";
}
};
// Function that search the given pattern
void searchPattern(string arr[], int N,
string str)
{
// Object of the class Dictionary
Dictionary* obj = new Dictionary();
for (int i = 0; i < N; i++) {
obj->addWord(arr[i]);
}
// Search pattern
obj->searchUtil(str);
}
// Driver Code
int main()
{
// Given an array of words
string arr[] = { "data", "date", "month" };
int N = 3;
// Given pattern
string str = "d.t.";
// Function Call
searchPattern(arr, N, str);
}
Searching for "d.t."
Found: data
Found: date
时间复杂度: O(M * log(N)),其中N是字符串数,M是给定模式的长度
辅助空间: O(26 * M)