c# - 从 C# 中的数据结构中查找带有一些 epsilon 的浮点数,同时搜索和插入 O(lg n) 时间
问题描述
在 C++ 中,我可以使用std::map<double, T>
它作为键的有序字典,但它是一个红黑树,它为我提供了 O(lg n) 的插入和搜索。我能够通过一起使用std::lower_bound和std::upper_bound来查找某个 epsilon 中是否存在值。
我在使用 C# 7+/.NET Core 时找不到相同的东西。这样的事情存在吗?
在伪代码中,我想做这样的事情
Map<float, T> map = ...
// key epsilon newValue
map.Insert(0.5f, 0.1f, someObj); // No values in the map, inserts fine
map.Get( 0.45f, 0.1f); // 0.45 +/- 0.1 contains 0.5, would return someObj
map.Get( 0.3f, 0.1f); // 0.3 +/- 0.1 does not include 0.5, it is not found
map.Insert(0.55f, 0.1f, anotherObj); // 0.55 +/- 0.1 includes 0.5, replace someObj
map.Insert(0.35f, 0.1f, anObj); // 0.35 +/- 0.1 doesn't overlap, insert new value
我必须这样做的方式是滚动我自己的自平衡二叉搜索树,但如果存在这样的事情,我宁愿不重新发明轮子。
我一直在看SortedDictionary
,但是它的Keys
领域是一个集合,所以我不能在里面跳来跳去。同样的问题OrderedDictionary
,除非我错过了什么。
我可能无法使用 SortedList,因为插入会比查找更多,并且由于随机顺序,我担心我最终会得到很多 O(n) 交换,需要在插入时完成. 我假设我的输入是均匀分布的(这很可能是因为我正在使用的数据),这意味着如果以这种方式实现它,向中间和前面的插入会导致很多变化我认为确实如此......这将使我平均花费 n/2 次插入并使我留在 O(n)。至少使用二叉搜索树,我得到 O(lg n)。因此,这里的好解决方案可能不适用。
最重要的是,这是一种在代码非常热门的部分中使用的算法。性能非常重要,选择不快的东西可能会严重损害应用程序的性能。我真的需要 O(lg n) 或一些我以前没有想到的新方法。
解决方案
我的想法是结合两个数据结构,SortedSet 和一个常规映射。
SortedSet 具有 GetViewBetween 方法,该方法具有预期的性能。 https://github.com/dotnet/corefx/pull/30921
注意:此方法的预期性能仅在 .NET 核心中得到满足,过去要慢得多:Why SortedSet<T>.GetViewBetween is not O(log N)?
在这个集合中,您只保留浮动键。此外,您还有一个从 float 到所需类型的 Map。只有在检查了 SortedSet 之后才能在地图上执行操作。
我意识到有一些粗糙的边缘(当一个间隔在 SortedSet 中给出一些条目时),但我相信这相当于 cpp 实现。
希望这对您有所帮助,祝您实施顺利。
推荐阅读
- robotframework - 如何在 Robot Framework 中的循环中执行循环
- android - 用户从 Android 应用中选择日期/时间后在日历中设置提醒
- php - Cycle 没有显示 SQL 中显示的所有结果
- sql - 当oracle中特定周不存在数据时如何将值填充为零
- java - Mocktio 可以模拟持久性提供程序,以便 jenkins(或其他管道工具)可以在没有数据库的情况下执行 JUnit 测试吗?
- pentaho - 无法从数据库结果集中获取值 'String(34)',索引 2
- php - 在 REST API 中搜索特定 id
- css - 如何在引导程序中设置下拉项的宽度?
- vue.js - 无法从选项列表中选择选项
- kubernetes - GKE 从 nodepool 开始非常慢 - 集群和 k8s/gcloud api 不可用