【问题标题】:Effective search with contains有效搜索包含
【发布时间】:2013-08-06 11:49:58
【问题描述】:

我有一个 Trie 数据结构,它可以在眨眼间搜索 100 000 个元素。但是它只搜索以搜索字符串开头的单词,例如“Fi”会找到“Final”但不会找到“GooFi”,我希望它也返回“GooFi”。这就是为什么我在这里问你们在这种情况下这是否是正确的结构。我自己实现了它,编写了单元测试,所以它到目前为止工作。我需要的是如何实现我的目标的提示,我不希望任何人为我编写代码,这不是我在这里的原因。无论如何,这是我的搜索实现:

public List<string> Seach(string word)
{
    List<string> results = new List<string>();
    this.DoSearch(this.Root, 0, new StringBuilder(word), results);
    return results;
}

private void DoSearch(TrieNode currentNode, int currentPositionInWord, StringBuilder word, List<string> results)
{
    if (currentPositionInWord >= word.Length)
    {
        this.DfsForAllWords(currentNode, word, results);
        return;
    }

    char currentChar = word[currentPositionInWord];

    bool containsKey = currentNode.Children.ContainsKey(currentChar);
    if (containsKey)
    {
        if (currentPositionInWord == word.Length - 1)
        {
            results.Add(word.ToString());
        }

        TrieNode child = currentNode.Children[currentChar];
        this.DoSearch(child, ++currentPositionInWord, word, results);
    }
}

private void DfsForAllWords(TrieNode currentNode, StringBuilder word, List<string> results)
{
    foreach (var node in currentNode.Children.ToArray())
    {
        word.Append(node.Value.Value);
        if (node.Value.IsWord)
        {
            results.Add(word.ToString());
        }

        this.DfsForAllWords(node.Value, word, results);
        word.Length--;
    }
}

非常感谢任何帮助。

【问题讨论】:

标签: c# string search trie


【解决方案1】:

您可以在所有节点上使用一种索引。

Dictionary&lt;char,List&lt;TrieNode&gt;&gt; nodeIndex;

现在,如果您想搜索“Fi”,请遍历 nodeIndex 并像以前一样搜索。如果您在该迭代中发现了某些内容,则必须在找到的子字符串前面加上通向实际节点的字符串。

public List<string> Seach(string word)
{
    List<string> results = new List<string>();

    foreach(var node in nodeIndex[word[0]])
    {
        List<string> nodeResults = new List<string>();

        this.DoSearch(node, 0, new StringBuilder(word), nodeResults);

        foreach(var nodeResult in nodeResults)
        {
            var text = string.Format("{0}{1}",node.Parent.Text, nodeResult);
            results.Add(node.Parent.Text, nodeResult);
        }
    }

    return results.Distinct().ToList();
}

也许您还需要实现一些尚未实现的属性。

【讨论】:

  • 感谢您的发帖,我想到了这一点,但是这似乎会浪费内存,因为我的目标之一是不浪费内存,因为我要处理大量数据。无论如何,我修改了 Trie 以在子字符串中搜索。稍后我将发布我的代码,以便更多人可以从中受益。
【解决方案2】:

https://github.com/gngeorgiev/Trie

如果有人需要,这里是 Trie 的 repo。支持前缀和子串搜索。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多