![](/img/trans.png)
[英]What read-only, order-preserving collection in C# should I use to support enumeration?
[英]What collection should I use for combining fastest key retrieval, but also fastest sorted enumeration in c#?
请有人向我推荐 c# 中的一些集合(或者也许是我自己实现它的提示)用于存储键值对,我将始终最多拥有 50 个这些键值对。 但通常只有 5-20 个键值对。 而且我需要绝对最快的检索给定键的值。 首先我想到了字典,因为它的检索访问时间为 O(1)。 但我仍然不确定为这么小的 collections 使用字典的开销。 但我猜即使对于像这样的小型 collections,Dictionary 也能提供最好的速度?
然后我有另一个要求,我需要能够告诉给定键的下一个更大的键(例如,我有值为 2、4、6、8、10、11、12、15 的键,当我说让我们说7,我需要能够快速判断,下一个比 7 更大的键是 8)。 于是想着把这些key的集合进行排序,这样就可以很快的分辨出下一个更大的key)。 我当时考虑使用 SortedDictionary,但我发现它的访问速度较慢 O(log(n)),但会为我提供寻找下一个更大密钥的另一个好处。
顺便说一句,通过这个集合的整个使用,它永远不会被修改,它只需要在开始时构建,这可能会很慢,对我来说构建它的速度无关紧要。 此外,我根本不关心 memory 的使用。
例如,我的解决方案也可以结合 Dictionary 和 SortedList。 将 2 个 collections 组合在一起,以最大限度地提高检索速度和“getNextBiggerKey”速度。
或者现在我也在考虑将 nextBiggerKey 存储在该键值对的值中。 因此,至少对于那些已经在收藏中的钥匙,它会给我下一个更大的钥匙。
那么有人有什么好主意吗,如何在这种情况下完全最大化性能?
更新:我所说的键实际上是分数类型的。 但是对于低值,分子和分母都不会大于 256,因此字节应该(很有可能)对它们都足够。
非常感谢您的帮助,将不胜感激:)
如果键实际上是 integer 如您所示,则计算 hash 来搜索元素没有任何优势(因此不需要散列键的集合)。 由于您可以构建一次列表,然后可以使用不可变列表,因此我认为二进制搜索是您可以获得的最快速度。
我首先要尝试的是 KeyValue 对的普通List<T>
,用项目填充它,对其进行一次排序,然后使用List.BinarySearch()搜索元素。 可以肯定的是,您应该对多个场景进行基准测试,但这肯定是一个好的开始。
这个答案假设可能的键范围很小(最多几千个)。 在这种情况下,您可以实现基于查找表的解决方案。 假设小数键的范围在 10 到 14 之间,包括一半和四分之一。 还假设您在此范围内有 4 个键,其值分别为 10、10 3/4、12 1/2 和 13。首先,您需要一种将键转换为 integer 的方法,该键将用作数组。 在这种情况下,翻译 function 将是:
f(x) = (x - 10) * 4
所以键 10 被转换为索引 0,键 14 被转换为索引 16。接下来您需要构造一个长度为 17(从 0 到 16)的数组。 下表显示了该数组的值:
| Key | Translated | Index | Value |
|---------|------------|---------|---------|
| 10 | 0 | 0 | 0 |
| 10 1/4 | 1 | 1 | 3 |
| 10 1/2 | 2 | 2 | 3 |
| 10 3/4 | 3 | 3 | 3 |
| 11 | 4 | 4 | 10 |
| 11 1/4 | 5 | 5 | 10 |
| 11 1/2 | 6 | 6 | 10 |
| 11 3/4 | 7 | 7 | 10 |
| 12 | 8 | 8 | 10 |
| 12 1/4 | 9 | 9 | 10 |
| 12 1/2 | 10 | 10 | 10 |
| 12 3/4 | 11 | 11 | 12 |
| 13 | 12 | 12 | 12 |
| 13 1/4 | 13 | 13 | -1 |
| 13 1/2 | 14 | 14 | -1 |
| 13 3/4 | 15 | 15 | -1 |
| 14 | 16 | 16 | -1 |
不,让我们使用这个数组进行一些搜索。
(12 - 10) * 4
得到索引 8。 array[8]
的值是 10。10 与 8 不同,因此键 12 不存在。array[3]
为 3,因此键存在,但我们对此不感兴趣。 我们需要查看下一个数组元素, array[4]
。 它的值为 10,它是键 12 1/4 的翻译。 所以下一个更大的 10 3/4 键是 12 1/4。现在您已经有了一种按键搜索此结构的方法,您可以考虑如何将每个键与一个值相关联,最终得到一个正确的字典。 最简单的方法可能是在混合中添加另一个长度相等的数组,将每个键的值存储在同一索引中。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.