需要快速插入、查找最近键和按键顺序迭代的关联数组
本文关键字:顺序 数组 关联 迭代 最近 插入 查找 | 更新日期: 2023-09-27 17:52:16
我正在执行类似于n维卷积的操作,但是为了节省内存和时间,我将合并彼此接近的值。
- 我在数组中查找一个键。
- 如果我找到键,我添加到存储在该键的值。
- 如果没有找到键,则查找下一个最高键和下一个最低键。
- 如果两个邻居中较近的那个足够近,那么我就累积那个键值对。
- 否则我添加一个新的键值对。
键是双精度类型。它总是正的,而不是无限的。(我专门处理零。)我预计价值从几美分到高达1000亿美元不等。当算法继续保持最大数组大小在10,000到1,000,000之间时,舍入粗度将发生变化。(只有测试才能揭示在速度、内存和准确性之间权衡的最佳点。)由于值的范围与数组大小的关系,直接寻址是不实际的;我需要稀疏存储
简单的方法是使用List并执行BinarySearch来查找键或插入点,然后从那里继续。这对于找到最近的键是很快的,可以按键顺序迭代,但插入是可怕的。(我不需要执行删除!外循环中的每次迭代都从零开始创建一个新列表。)
推荐使用哪种数据结构?Wikipedia提到了一些,比如Trie、Judy array等。
(几年前我实现了一些类似于try的东西,但那是在java中实现的,花了我一周的时间来实现,而且很棘手。我时间很紧
更新:SortedSet的建议使我修改了我的需求。而找到下一个最低和下一个最高的键是我完成任务的方式,SortedSet。GetViewBetween处理事情的方式不同。因为我只是想看看是否有一个足够接近的值可以聚合,并且我有一个特定的舍入粒度G,所以我可以使用
请求所有感兴趣的元素。var possibilities = mySet.GetViewBetween(x - G, x + G)
如果该集合为空,则需要添加,如果不是,则可能是一个小集合,并遍历它。
我需要执行性能测试,看看它是否足够快。但即使没有,另一个具有相同契约的集合也是FindNextHighestKey和FindNextLowestKey的可接受替代方案。
更新2:我决定使用普通的Dictionary,并使用自定义舍入函数将键强制放入桶中。按排序顺序迭代条目并不重要,通过使用这个舍入函数,我可以找到"足够接近"的值来进行聚合。我不会在迭代期间更改粒度;每次完成一个新维度的卷积后,我都会调整它。每次迭代我都会创建一个新数组来保存该遍历的结果。
如果您的密钥是唯一的,您可以查看Dictionary<TKey,TValue>
或SortedDictionary<TKey,TValue>
我发现了这个问题,这让我想到了SortedSet<T>
。
如果您可以处理O(log(n))的插入、删除和查找操作,那么您应该将密钥保存在这里。
根据您的新要求…为什么不在使用前通过粒度将双精度映射到稀疏键并使用Dictionary<double, T>
?如果您希望在运行时更改粒度,那么这种方法将不起作用,但其他方法也不会起作用。