C# 包含的有效搜索

C# 包含的有效搜索,c#,string,search,trie,C#,String,Search,Trie,我有一个Trie数据结构,它在一眨眼之间搜索100000个元素。但是,它只搜索以搜索字符串开头的单词,例如“Fi”将找到“Final”,但不会找到“GooFi”,我希望它也返回“GooFi”。这就是为什么我在这里问你们,在这种情况下,这是不是正确的结构。我自己实现了它,编写了单元测试,所以到目前为止它仍然有效。我需要的是一个如何实现我的目标的提示,我不希望任何人为我编写代码,这不是我在这里的原因。无论如何,这是我的搜索实现: public List<string> Seach(str

我有一个Trie数据结构,它在一眨眼之间搜索100000个元素。但是,它只搜索以搜索字符串开头的单词,例如“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--;
    }
}
公共列表搜索(字符串字)
{
列表结果=新列表();
this.DoSearch(this.Root,0,新的StringBuilder(word),结果);
返回结果;
}
私有void DoSearch(三节点currentNode、int-currentPositionInWord、StringBuilder word、列表结果)
{
如果(currentPositionInWord>=字长)
{
此.DfsForAllWords(currentNode、word、results);
返回;
}
char currentChar=字[currentPositionInWord];
bool containsKey=currentNode.Children.containsKey(currentChar);
if(containsKey)
{
if(currentPositionInWord==word.Length-1)
{
添加(word.ToString());
}
三节点子节点=currentNode.childrent[currentChar];
this.DoSearch(child,++currentPositionInWord,word,results);
}
}
私有无效DFSFORALLWORD(三节点currentNode、StringBuilder word、列表结果)
{
foreach(currentNode.Children.ToArray()中的var节点)
{
追加(node.Value.Value);
if(node.Value.IsWord)
{
添加(word.ToString());
}
this.DfsForAllWords(node.Value、word、results);
字长;
}
}

非常感谢您的帮助。

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

字典节点索引

现在,如果您想搜索例如“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();
}
公共列表搜索(字符串字)
{
列表结果=新列表();
foreach(nodeIndex[word[0]]中的var节点)
{
List nodeResults=新列表();
this.DoSearch(节点,0,新StringBuilder(word),节点结果);
foreach(节点结果中的变量nodeResult)
{
var text=string.Format(“{0}{1}”,node.Parent.text,nodeResult);
添加(node.Parent.Text,nodeResult);
}
}
返回结果.Distinct().ToList();
}
也许您必须实现一些尚未实现的属性。


这是Trie的回购协议,如果有人需要的话。支持前缀和子字符串搜索。

如何-对于搜索子字符串,trie与普通列表或数组相比没有任何好处,因为您必须检查所有字符串。对于一些想法:那么后缀树呢?谢谢你的帖子,我想到了这一点,但是这似乎会浪费内存,因为我的目标之一是不浪费内存,因为我要处理大量数据。无论如何,我修改了Trie以在子字符串中搜索。我将稍后发布我的代码,这样更多的人可以从中受益。