Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 需要在插入、查找最近的键和按键顺序迭代时快速的关联数组_C#_Algorithm_Associative Array - Fatal编程技术网

C# 需要在插入、查找最近的键和按键顺序迭代时快速的关联数组

C# 需要在插入、查找最近的键和按键顺序迭代时快速的关联数组,c#,algorithm,associative-array,C#,Algorithm,Associative Array,我正在执行类似于N维卷积的操作,但在继续操作时将合并彼此接近的值,以节省内存和时间 我在数组中查找一个键 如果我找到了键,我会将存储在该键上的值相加 如果我找不到键,我会找到下一个最高键和下一个最低键 如果两个邻居中较近的一个足够近,那么我将使用该键值对进行累加 否则,我将添加一个新的键值对 钥匙是双钥匙。它总是积极的,而不是无限的。(我专门处理零)我预计这些值的范围从几便士到高达1000亿。舍入粗糙度将随着算法的进行而改变,以将最大数组大小保持在10000到1000000之间。(只有测试才能揭

我正在执行类似于N维卷积的操作,但在继续操作时将合并彼此接近的值,以节省内存和时间

  • 我在数组中查找一个键
  • 如果我找到了键,我会将存储在该键上的值相加
  • 如果我找不到键,我会找到下一个最高键和下一个最低键
  • 如果两个邻居中较近的一个足够近,那么我将使用该键值对进行累加
  • 否则,我将添加一个新的键值对
  • 钥匙是双钥匙。它总是积极的,而不是无限的。(我专门处理零)我预计这些值的范围从几便士到高达1000亿。舍入粗糙度将随着算法的进行而改变,以将最大数组大小保持在10000到1000000之间。(只有测试才能揭示速度、内存和准确性之间的最佳平衡点。)由于值的范围与数组大小的关系,直接寻址不实用;我需要稀疏存储

    最简单的方法是使用列表并执行二进制搜索来查找键或插入点,然后从那里开始。这对于查找最近的键很快,可以按键顺序迭代,但插入很可怕。(我不需要执行删除!外部循环中的每次迭代都会从头开始创建一个新列表。)

    推荐什么样的数据结构?维基百科提到了一些,比如Trie、Judy array等

    (几年前我实现了类似Trie的东西,具有类似的特性,但那是用java实现的,花了我一周的时间才实现,而且很棘手。我的时间紧迫。)

    更新:

    SortedSet的建议导致我修改我的需求。虽然找到下一个最低和下一个最高的键是我完成任务的方式,但SortedSet.GetViewBetween处理事情的方式不同。因为我只是想看看是否有一个足够接近的值可以聚合,并且我有一个特定的舍入粒度G,所以我可以使用

    var possibilities = mySet.GetViewBetween(x - G, x + G)
    
    如果该集合为空,我需要添加。如果不是,它可能是一个小集合,我将遍历它

    我需要进行性能测试,看看它是否足够快。但是,即使没有,具有相同契约的另一个集合也是FindNextHighestKey和FindNextLowestKey的可接受替代方案

    更新2:


    我决定使用普通字典,并使用自定义舍入函数将键强制放入桶中。按排序顺序迭代项目并不重要,通过使用这个舍入函数,我可以找到“足够接近”的值来进行聚合。我不会在迭代过程中更改粒度;我将在每次使用新维度完成卷积时进行调整。每次迭代我都会创建一个新数组来保存该过程的结果。

    如果您的密钥是唯一的,您可以查看我找到的
    字典
    SortedDictionary

    如果您可以为插入、删除和查找处理O(log(n)),那么这可能是您应该保存密钥的地方



    根据您的新要求。。。为什么不在使用前将双精度映射到稀疏键,然后使用
    字典
    ?如果您希望在运行时更改粒度,这将不起作用,但另一种方法也不起作用。

    我知道没有内置的集合支持这一点。BCL对有序收集的支持很糟糕,不是家庭作业。其应用是对飓风造成的N个属性的概率损失进行N倍卷积,以获得损失的预期值。保险风险分析。您将如何实现“如果我没有找到密钥,我将找到下一个最高和下一个最低的密钥。”我不认为有一种有效的机制可以从这两种方法中获取“相邻密钥”。有一种有效的方法可以查看密钥是否在x-k和x+k之间:为字典编写一个自定义比较器,以强制执行粒度要求。然而,随着我的算法的进行,我将根据需要扩大粒度,一旦您向字典中添加项,最好不要中途更改比较器!最后,简单的旧字典是我一直需要的。它没有回答我所说的问题,但它完成了任务。在添加值之前,我对其键进行四舍五入,但存储具有未舍入值的结构。然后,为了寻找一个值,我将搜索的键四舍五入并返回该值。最难的部分是编写一个舍入函数…使用起来似乎有点烦人,但应该可以用它实现二元搜索。@CodesInChaos这是一个二元搜索树。您只需调用SortedSet.Contains进行二进制搜索。它没有实现IList,所以prev和next元素有点棘手。我想GetViewBetween可能会有帮助(因为窗口边界是已知的)。看起来很接近我需要的。我考虑过红黑树,知道SortedSet,但它没有“FindClosest”方法。但是,我不知道“GetViewBetween”方法。如果它是有效的,我可以用它来完成我的任务。我将进行调查。Raymond Chen就GetViewBetween的“性能问题”发表了评论。GetViewBetween似乎对视图中的元素进行计数,因此您需要相当确定您没有获得大视图(听起来您已经在这样做了)。+1对您来说,David B。我正要编写性能测试。很明显,SortedSet将不会对我执行该帖子中突出显示的问题。