我有一个相对较大的数据集,非常自然地适用于c#的字典对象。目前,我有102400个键值对,在我的程序启动时半动态生成。我的问题是我必须尽快运行大量的查找操作。
根据This Page,查找的速度直接受字典中键值对的数量的影响。我的数据有点奇怪,因为大量不同的键导致相同的值。事实上,我只有4900个不同的值...这意味着每个不同的值平均有20个键值对。
我的第一直觉是交换值的键(因为我只关心数据中的不同值)然后将列表或数组中的旧键作为新值。这使我的字典大小从102400个键值对减少到4900,但是我看不出有效搜索所有列表中的特定值来获取密钥的方法。
我知道当我切换键和值时,我的描述可能有点难以理解,所以我已经包含了一个模拟我的数据来向你展示我的意思:
旧方法:
Key Value
--- -----
1 1
2 2
3 3
4 1
5 3
6 2
7 2
8 1
9 3
10 2
11 3
12 1
新结构:
Key Value
--- -----
1 {1,4,8,12}
2 {2,6,7,10}
3 {3,9,5,11}
在我的计划中,我将获得'11',我将需要返回'3'。第一个结构是一个简单的查找,但是一个巨大的列表似乎正在减慢速度......第二个结构增加了很多逻辑开销来追踪我正在寻找的值列表我只看到了减少试图实现它的速度。
我在这里咆哮错误的树吗?我应该只接受较大列表的速度,还是有其他方法可以存储我的数据以提高查找速度?
答案 0 :(得分:2)
如果所有键都是不同且连续的,那么你应该考虑一个简单的数组;如果密钥不是连续的,那么如果它们不是哈希映射类型的结构。如果散列函数是好的,这将接近O(1),如果它们都是整数,则不应占用太多空间。
即使这样,对于102400个元素,二进制树查找每次查找最多需要log2(102400)次操作,这是16.64次操作,并不是很慢。
答案 1 :(得分:2)
使用Lookup(.NET 3.5及更高版本)。
来自MSDN:
查找(TKey,TElement)
表示每个映射到一个或多个值的键集合。
编辑: 顺便说一句,如果你的所有键都是连续的(即1,2,3,...),请使用一个简单的数组。
答案 2 :(得分:0)
如果您的密钥不连续,那么字典就是您的选择。我不知道这种数据的任何更快的查找方法。您的示例显示了连续的顺序数据,这些数据可以从将值直接存储在数组中并直接跳转到基于密钥的正确索引中获益。只要您的真实数据的键模仿您的示例键,我就会使用数组。
答案 3 :(得分:0)
有一次你做了新的结构,就像我理解的那样,
Dictionary<first, List<second>>
,其中first
和second
是整数。
您可以注意List<second>
的内容是有序的事实。
考虑到你挑战不是快速的数据组合,而是快速访问和恢复,拥有List<second>
将让你执行安全{{3} },在列表项中查找数据的最快方法。