我有一个排序字典,其中包含作为键/值对的测量数据点。为了确定非测量数据点的值,我想使用对应值的线性插值来推断两个已知键之间的值。一旦我拥有了位于其之间的两个键/值对,我就了解如何计算非测量数据点。我不知道的是如何找出它位于哪些键之间。有没有比“for”循环(我正在考虑函数/LINQ 查询)更优雅的方法来找出我的数据点位于哪两个键之间?
I have a sorted dictionary that contains measured data points as key/value pairs. To determine the value for a non-measured data point I want to extrapolate the value between two known keys using a linear interpolation of their corresponding values. I understand how to calculate the non-measured data point once I have the two key/value pairs it lies between. What I don't know is how to find out which keys it lies between. Is there a more elegant way than a "for" loop (I'm thinking function/LINQ query) to figure out which two keys my data point lies between?
发布评论
评论(5)
像这样的东西会起作用:
这会使用它们是有序的这一事实来遍历它们的键,并按顺序比较彼此后面的所有两个键 - 因为 LINQ 是惰性的,一旦找到第一个匹配项,遍历就会停止。
Something like this would work:
This traverses they keys using the fact that they are ordered and compares all two keys following each other in order - since LINQ is lazy once you find the first match the traversal will stop.
标准 C# 答案的复杂度都是 O(N)。
有时您只需要相当大的排序集合中的一个小子集。 (所以你没有迭代所有的键)
标准 C# 集合在这里无法为您提供帮助。并且解决方案如下:
http://www.itu.dk/research/c5/ 在 C5 中使用 IntervalHeap馆藏图书馆。此类支持 GetRange() 方法,并且将以 O(log N) 复杂度查找起始键,并以 O(N) 复杂度迭代范围。如果性能至关重要的话,这对于大数据集绝对有用。例如游戏中的空间分区
The standard C# answers are all O(N) complexity.
Sometimes you just need a small subset in a rather large sorted collection. (so you're not iterating all the keys)
The standard C# collections won't help you here. And a solution is as followed:
http://www.itu.dk/research/c5/ Use the IntervalHeap in the C5 collections library. This class supports a GetRange() method and will lookup the startkey with O(log N) complexity and iterate the range with O(N) complexity. Which will be definately useful for big datasets if performance is critical. e.g. Spatial Partitioning in gaming
您可能会问以下问题:
Possible you're asking about following:
常规循环在这里应该没问题:
您可以使用更短但效率较低的代码在 C# 中使用 LINQ 来完成此操作:
为了有效地使用 LINQ,它应该有一个名为 在 F# 中使用参数 2 进行窗口化。它将返回
keys< 中相邻对的
IEnumerable
/代码> 集合。虽然 LINQ 中缺少此函数,但常规foreach
循环应该没问题。regular loop should be ok here:
You can do it in C# with LINQ with shorter but less effective code:
In order to it efficiently with LINQ it should have a method which is called windowed in F# with parameter 2. It will return an
IEnumerable
of adjacent pairs inkeys
collection. While this function is missing in LINQ regularforeach
loop should be ok.我认为 SortedDictionary 上没有一个函数可以让您比迭代元素更快地找到所需元素周围的元素。 (+1 到 BrokenGlass 解决方案)
为了能够更快地找到物品,您需要切换到其他结构。即 SortedList 提供类似的功能,但允许索引其 Key 集合,因此您可以使用二进制搜索来查找范围。
I don't think there is a function on SortedDictionary that lets you find elements around the one you need faster than iterating elements. (+1 to BrokenGlass solution)
To be able to find items faster you need to switch to some other structure. I.e. SortedList provides similar functionality but allows to index its Key collection and hence you can use binary serach to find the range.