搜索三数据结构

本文关键字:数据结构 搜索 | 更新日期: 2023-09-27 18:32:02

我有大约 150,000 个单词加载到 Trie 数据结构中,想要搜索它。每次我在搜索框中输入一个新字符时,该字符将作为 NextMatch 的参数传递。

例如:如果我输入"Appl",那么所有以"Appl"开头的单词都将返回。如果我输入字符"e",则会显示所有以"Apple"开头的单词。

问题是,当我删除字符"e"时,"l"将作为 NextMatch 的参数传递给 Matcher 方法并找到类似"Appll"的内容,但我想要以"Appl"开头的单词列表。

这是我的代码狙击

private void searchBox_TextChanged(object sender, TextChangedEventArgs e)
{
    listboxWords1.Items.Clear();
    if (searchBox.Text.Length > 0)
    {
        trie.Matcher.NextMatch(searchBox.Text.Trim().Last());
        foundWords = trie.Matcher.GetPrefixMatches(); //foundWords is List<string>
        for (int i = foundWords.Count - 1; i > 0 ; i--)
        {
            listboxWords1.Items.Add(foundWords[i]);
        }
        foundWords = null;
        isFoundExact = trie.Matcher.IsExactMatch();
        if (isFoundExact)
            listboxWords1.Items.Add(trie.Matcher.GetExactMatch());
    }
    else
    {
        foundWords = null;
        trie.Matcher.ResetMatch();
    }
}

Trie 数据结构的实现可以在这里找到

搜索三数据结构

似乎 API 是单向的,但这很好,我们可以从一开始就重新计算匹配项。

Trie 的计算复杂性不是那么大,因此您不会感到任何性能问题。

private void searchBox_TextChanged(object sender, TextChangedEventArgs e)
{
    listboxWords1.Items.Clear();
    if (searchBox.Text.Length > 0)
    {
        trie.Matcher.ResetMatch();//Reset the match
        foreach (char c in searchBox.Text)
            trie.Matcher.NextMatch(c); //Start the match from beginning 
        foundWords = trie.Matcher.GetPrefixMatches(); //foundWords is List<string>
        for (int i = foundWords.Count - 1; i > 0 ; i--)
        {
            listboxWords1.Items.Add(foundWords[i]);
        }
        foundWords = null;
        isFoundExact = trie.Matcher.IsExactMatch();
        if (isFoundExact)
            listboxWords1.Items.Add(trie.Matcher.GetExactMatch());
    }
    else
    {
        foundWords = null;
        trie.Matcher.ResetMatch();    
    }
}

没有经过测试,但这应该给你一个想法。如果用户键入速度非常快,并且您希望避免非常频繁地计算,则可以使用一些限制逻辑来延迟搜索算法。