先决条件:尝试 | (插入和搜索)
给定的字符串话[]和一个局部字符串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.”
方法:
Trie节点的结构:思想是使用Trie来解决给定的问题以下是trie的步骤和结构:
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 并将指针指向这个新节点并且在这个新节点处为下一个字符重复该过程。对于最后一个字符的 TrieNode 指针指向的 TrieNode, endOfWord为真。
- 用于搜索关键字,检查在由字符标记的索引处是否存在 TrieNode。如果存在,我们向下移动分支并为下一个字符重复该过程。类似地搜索部分字符串if a ‘.’找到后,我们在 children 数组中查找所有可用的 TrieNode 指针,并进一步处理每个字符,由索引标识,占据‘.’的位置。一次。
- 如果在任何时候指针位置为空,我们将返回未找到。否则在最后一个TrieNode处检查 endOfWord,如果为 false,我们返回 not found,否则找到 word。
下面是上述方法的实现:
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)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。