【问题标题】:Searching for a substring in a key of a key-value pair more efficient when stored in a data structure or in a long string?当存储在数据结构或长字符串中时,在键值对的键中搜索子字符串更有效?
【发布时间】:2012-12-08 08:06:08
【问题描述】:

我有一个字符串搜索问题,我想到了两个关于如何实现它的想法。我想知道人们是否可以指出哪种方法会给我带来更高效的性能,或者甚至可以提出更好的方法?

问题是我有一个大约 450kb 的文本文件,其中包含以下格式的数据:

description1, code1\n
description2, code2\n
description3, code3\n
...

它是由逗号分隔的两列数据,每条记录由一个描述和一个代码组成。

代码是一个简短的三字符文本,对用户没有直接意义,这就是为什么有与代码配对的描述数据。

description 数据是一个简短的句子,向用户描述了code 的含义。

我正在尝试创建一个 GUI,用户可以在其中在可编辑的文本字段中输入搜索关键字,然后用于搜索描述数据。然后系统将返回所有过滤的记录,即所有具有关键字作为子字符串的描述数据以及与之配对的代码供用户选择。用户键入的每个字符都会发生这种情况。

想到如何实现这个特性的第一个想法是创建一个以描述数据为key的键值对集合,比如NameValueCollection,然后使用foreach循环遍历每条记录并搜索匹配子字符串的键。

第二个想法是将整个文本文件读入一个长字符串,并使用String.IndexOf()方法搜索关键字,只要搜索到,我就提取该部分记录返回用户。

我想到了第二个想法,因为我担心第一个想法可能对性能产生影响。我读过IndexOf 方法与StringComparison.Ordinal 一起使用的性能比Boyer–Moore 字符串搜索算法要好,所以我认为以这种方式实现它会有更好的性能?

那么,在键中搜索子字符串时,是否可以更快地检索将整个文件存储为字符串或 NameValueCollection,或者有更好的方法吗?

【问题讨论】:

  • 450k 太小了。你不需要任何花哨的东西。天真的蛮力一眨眼就行了。
  • 真的吗?我在想我需要一些非常快的东西,因为用户正在搜索所有输入的字符的所有记录。也许我会先测试一下,然后再朝花哨的方向发展。
  • time grep foo /usr/share/dict/words 在我的机器上需要 .041s,即读取 910kb 文件。您的搜索不会像 grep 那样快,但您已经将数据保存在内存中。人类反应时间约为 0.25 秒
  • @rrenaud:即使人类对事物的反应速度不能超过 250 毫秒,但他们检测同时或单独事件的能力要好得多。虽然将屏幕更新推迟到最后一次击键后半秒可能会比每次击键后更新在视觉上更分散注意力,但即使是 100 毫秒的延迟也足以让某些东西明显“非即时”。

标签: c# asp.net data-structures key-value


【解决方案1】:

如果您有大量字符串并计划搜索完全相同的子字符串,那么您有很多可用选项。

一种选择是使用Aho-Corasick string matching algorithm 在文件的每一行中搜索搜索查询。执行此操作的总运行时间为 O(m + n + z),其中 m 是查询的长度,z 是总匹配数,n 是文件中所有字符串的字符总数.

一个更好但更复杂的选择是从文件的所有行中构建一个generalized suffix tree。然后,您可以在 O(n + z) 时间内找到所有匹配行,其中 n 是要搜索的模式的长度,z 是文件中的总行数。这需要 O(m) 预处理时间,其中 m 是文件中的字符总数。这比第一个选项快得多,但您可能必须找到一个好的后缀树库,因为后缀树构造算法相当复杂。

希望这会有所帮助!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-02-09
    • 1970-01-01
    • 2012-02-18
    • 2014-03-09
    • 2018-05-11
    • 2020-12-21
    • 2021-09-13
    相关资源
    最近更新 更多