【发布时间】:2015-04-24 04:43:50
【问题描述】:
我目前正在为实践进行 trie 实现,但遇到了心理障碍。
问题在于我的搜索功能。我试图让我的 trie 树在加载到程序内存后能够从提供的前缀中检索字符串列表。
我也知道我可以使用队列/不应该在 C++ 等中使用 C 函数。可以说这只是一个“草稿”。
这是我目前所拥有的:
bool SearchForStrings(vector<string> &output, string data)
{
Node *iter = GetLastNode("an");
Node *hold = iter;
stack<char> str;
while (hold->visited == false)
{
int index = GetNextChild(iter);
if (index > -1)
{
str.push(char('a' + index));
//current.push(iter);
iter = iter->next[index];
}
//We've hit a leaf so we want to unwind the stack and print the string
else if (index < 0 && IsLeaf(iter))
{
iter->visited = true;
string temp("");
stringstream ss;
while (str.size() > 0)
{
temp += str.top();
str.pop();
}
int i = 0;
for (std::string::reverse_iterator it = temp.rbegin(); it != temp.rend(); it++)
ss << *it;
//Store the string we have
output.push_back(data + ss.str());
//Move our iterator back to the root node
iter = hold;
}
//We know this isnt a leaf so we dont want to print out the stack
else
{
iter->visited = true;
iter = hold;
}
}
return (output.size() > 0);
}
int GetNextChild(Node *s)
{
for (int i = 0; i < 26; i++)
{
if (s->next[i] != nullptr && s->next[i]->visited == false)
return i;
}
return -1;
}
bool IsLeaf(Node *s)
{
for (int i = 0; i < 26; i++)
{
if (s->next[i] != nullptr)
return false;
}
return true;
}
struct Node{
int value;
Node *next[26];
bool visited;
};
代码太长或者我会全部发布,GetLastNode() 检索传入数据末尾的节点,所以如果前缀是 'su' 并且字符串是 'substring' 节点将是指向用作人工根节点的“u”
【问题讨论】:
-
为什么不使用递归实现?查看键的第一个字符:如果该字符与当前节点的其中一个子节点匹配,则从键中删除 char 并递归到其中,然后将该字符添加到所有响应中。如果键为空,则递归到所有孩子,加入来自不同调用的响应。
-
当我尝试在我的代码中编写递归函数时,我仍然很挣扎,如果要修复我已经编写的内容,我会更难做到这一点。
-
在我原来的问题上再补充一点:我添加了以下词{“the”、“a”、“there”、“answer”、“any”、“by” , "bye", "anytime" } 进入我的特里树,然后我搜索任何以 "an" 开头的东西,我得到 {"answer", "anytime"} 的输出,但它忽略了 "any"。这应该是一个简单的修复,但它让我头疼
-
好的,删除了我的答案,因为我相信它会遇到和你一样的问题。我认为您的问题是
IsLeaf()您的结构无法区分没有条目的节点(即a-n-y-前缀到anywhere)和具有条目a-n-y的节点