【问题标题】:How to implement incremental search on a list如何在列表上实现增量搜索
【发布时间】:2010-10-14 01:56:46
【问题描述】:

我想在字符串列表上实现增量搜索。考虑我有一个数组,其中包含字符串 store、state、stamp、crawl、crow。我的应用程序有一个文本框,用户可以在其中输入搜索字符串。现在,当用户输入文本时,我需要突出显示所有匹配项。例如,当用户输入“st”时,我现在需要突出显示“Store,state,stamp”,当他输入“a”时,我需要从列表中删除“Store”。我正在使用 c# 和 .net 开发应用程序框架。我打算做的是,在文本更改的事件中,我在后台进行搜索并显示结果。有没有其他方法可以解决这个问题?

【问题讨论】:

  • 当要匹配的字符串发生变化时,是否要从当前位置继续?还是要从头开始?

标签: c# .net search


【解决方案1】:

好吧,我已经为这个问题实现了一个 Trie 和一个 DAWG,我偶然发现了 2 个头部抓挠器:

1) DAWG --> 定向 ACYCLIC 字图。您如何使用“bot”和“boot”之类的词创建此图形/遍历它启动中的“oo”会导致基于 DAWG 的循环 2) Trie 消除了这个问题,但随后引入了一些分支管理问题。

构建图表(IMO)比实际使用它来生成您想要的单词要容易得多,而且不会产生更多的运行时间。

我仍在努力。

【讨论】:

  • 解决方案是不使用 DAWG 而是使用 Trie。这就像类固醇的基数排序。
【解决方案2】:

哇...

只需使用文本框上的内置自动完成功能。您可以向它提供您的单词列表,它会为您进行匹配。

【讨论】:

    【解决方案3】:

    你可以只看新输入的字母;如果新的第三个字母是“a”,则只需在位置三丢弃所有没有“a”的元素。如果用户删除了一封信,您必须重新扫描整个原始列表并恢复所有被私下删除的项目。

    但是如果用户从剪贴板粘贴多个字母,通过选择它们删除多个字母,在中间某处插入或删除单个或多个字母怎么办?

    您有很多情况需要注意。如果搜索文本以添加单个字母以外的方式发生变化,您可以使用新输入的字母执行该方法并回退到完全重新扫描,但即使是这种简单的方法也可能不值得仅仅为了避免几个十或百串比较。如前所述,如果您拥有非常大的数据集或想要非常快,那么TriePatricia trie 是您的最佳选择。

    【讨论】:

    • 你能推荐一些做这种工作的图书馆吗?
    【解决方案4】:

    我过去曾做过类似的事情,使用包含大约 500,000 个单词的集合。我发现directed acyclic word graph 运作良好。 DAWG 的性能与 trie 大致相同,但空间效率更高。但是,实现起来稍微复杂一些。

    很遗憾,我的工作是用 C 语言编写的,我没有很好的参考资料来了解用 C# 实现的 DAWG。

    【讨论】:

      【解决方案5】:

      如果您的列表可以增长到相当长的长度(超过数百个条目),trie data structure 会很好地扩展。检查例如this example implementation

      【讨论】:

      • 这就是我们不链接的原因。示例实现链接已过期。
      【解决方案6】:

      您可以使用泛型集合来代替字符串数组。这样您就可以使用 FindAll 方法和委托来搜索项目。

      string searchString = "s";
      List<string> sl = new List<string>();
      sl.Add("store");
      sl.Add("state");
      sl.Add("stamp");
      sl.Add("crawl");
      sl.Add("crow");
      List<string> searchResults = sl.FindAll(delegate(string match) 
                                                      { 
                                                          return   match.StartsWith(searchString, StringComparison.CurrentCultureIgnoreCase); 
                                                      });
      

      【讨论】:

        【解决方案7】:

        下面是一个函数,它将逐步搜索字符串以查找要匹配的子字符串。

        public IEnumerable<int> FindAllMatches(string toMatch, string source) {
          var last = 0;
          do {
            var cur = source.IndexOf(toMatch,last);
            if ( cur < 0 ) {
              break;
            }
            yield return cur;
            last = cur + toMatch.Length;
          while(true);
        }
        

        【讨论】:

        • 每次更改要匹配的字符串时,都会从头开始搜索。
        猜你喜欢
        • 2011-11-25
        • 1970-01-01
        • 1970-01-01
        • 2011-02-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-25
        相关资源
        最近更新 更多