哪种C#数据结构允许最有效地搜索一对字符串用于子字符串?

时间:2012-01-24 22:54:41

标签: c# .net search dictionary substring

我有一个由数对组成的数据结构,第一个是整数,第二个是字母数字字符串(可以用数字开头):

+--------+-----------------+
| Number | Name            |
+--------+-----------------+
| 15     | APPLES          |
| 16     | APPLE COMPUTER  |
| 17     | ORANGE          |
| 21     | TWENTY-1        |
| 291    | 156TH ELEMENT   |
+--------+-----------------+

这些表格最多包含100,000行。

我想提供一个查找功能,用户可以在其中查找数字(就像它是一个字符串)或字符串片段。理想情况下,查找将在用户输入时“实时”;在每次击键之后(或者在短暂延迟~250-500 ms之后),将进行新的搜索以找到最可能的候选者。所以,例如搜索

  • 1将返回15 APPLES16 APPLE COMPUTER17 ORANGE291 156TH ELEMENT
  • 15会将搜索范围缩小到15 APPLES291 156TH ELEMENT
  • AP将返回15 APPLES16 APPLE COMPUTER
  • (理想情况下,但不是必需的)ELEM将返回291 156TH ELEMENT

我正考虑使用两个Dictionary<string, string>,因为最终int被比较为string s - 一个将由整数部分索引,另一个将由字符串部分索引。

但是真正通过子串搜索不应该使用哈希函数,使用两倍于我觉得我应该需要的内存似乎很浪费。

最终的问题是,是否有任何表现良好的方法同时为两个大字符串搜索两个大型列表?

如果失败了,SortedDictionary怎么样?可能会提高性能,但仍无法解决哈希问题。

考虑即时创建正则表达式,但我认为这会表现得非常糟糕。

我是C#的新手(来自Java世界)所以我还没有考虑过LINQ;是答案吗?

编辑18:21 EST :“名称”字段中的所有字符串都不会超过12-15个字符,如果这会影响您的潜在解决方案。

3 个答案:

答案 0 :(得分:6)

如果可能的话,我会避免将所有100,000个条目加载到内存中。我会使用数据库或Lucene.Net来索引值。然后使用适当的查询语法有效地搜索结果。

答案 1 :(得分:3)

我考虑使用Trie数据结构。

如何实现?叶子代表你的“行”,但你会有“两条路径”到“行”的每个内存实例(一个用于数字,另一个用于名称)。

然后你可以牺牲自己的条件:

(ideally, but not required) ELEM will return 291 156TH ELEMENT.

或者为行实例提供更多路径。

答案 2 :(得分:1)

由于您正在搜索单词的开头,因此基于键的集合将不起作用,除非您存储所有可能的单词,例如“a”,“ap”,“app”,“appl”,“apple” 。

我的建议是将System.Collections.Generic.List<T>与二进制搜索结合使用。您必须提供自己的IComparer<T>,它也会找到单词的开头。您将使用两种数据结构。

一个List<KeyValuePair<string,int>>持有单个字或数字作为键,数字作为值。

一个Dictionary<int,string>持有全名。

你会这样做:

  1. 将您的句子(全名)分成单个单词。

  2. 将它们添加到列表中,并将单词作为键,并将数字作为KeyValuePair的值。

  3. 将数字添加到列表中作为键和KeyValuePair的值。

  4. 当列表已满时,对列表进行排序以允许二进制搜索。

  5. 搜索单词的开头:

    1. BinarySearchIComparer<T>结合使用,在列表中进行搜索。

    2. 您从搜索中获得的索引可能不是第一个适用的索引,因此请返回列表,直到找到匹配的第一个条目。

    3. 使用列表中存储为值的数字,使用此数字作为键在字典中查找整个名称。