如何从 SortedDictionary 获取上一个键?
我有包含键值对的字典。
SortedDictionary<int,int> dictionary=new SortedDictionary<int,int>();
dictionary.Add(1,33);
dictionary.Add(2,20);
dictionary.Add(4,35);
我想从已知的键值中获取先前的键值对。在上面的例子中,如果我有密钥4,那么我怎样才能得到<2,20>
?
I have dictionary containing key value pairs.
SortedDictionary<int,int> dictionary=new SortedDictionary<int,int>();
dictionary.Add(1,33);
dictionary.Add(2,20);
dictionary.Add(4,35);
I want to get previous key value pair from a known key value. In the above case, if I have key 4, then how can I get <2,20>
?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
使用
SortedDictionary
很难有效地实现这一点,因为它是作为不公开前驱或后继的二叉搜索树实现的。您当然可以枚举每个 KeyValuePair,直到找到“已知”键。使用一点 LINQ,这看起来像(假设该键肯定存在并且不是第一个键):
如果这些假设不成立,您可以这样做:(
检查
maybePreviousKvp != null 以确定先前的 KeyValuePair 已成功检索。)
但这根本不会有效。
如果可行,请考虑使用
SortedList< /code>
相反(显然,如果您不能接受其较慢的插入和删除,这可能是不可能的)。该集合支持通过有序索引进行高效的键和值检索,因为它是作为可增长数组实现的。然后,您的查询变得非常简单:
IndexOfKey
在键列表上运行二分搜索,运行时间为O(log n)
。其他一切都应该以恒定时间运行,这意味着整个操作应该以对数时间运行。否则,您必须自己实现/找到一个确实公开前驱/后继的 BST 集合。
It's hard to implement this efficiently with a
SortedDictionary<TKey, TValue>
since it is implemented as a binary search tree that does not expose predecessors or successors.You could of course just enumerate each KeyValuePair until you find the "known" key. With a little bit of LINQ, this would look like (assuming the key definitely exists and isn't the first key):
If those assumptions don't hold, you could do:
(Check that
maybePreviousKvp != null
to ascertain that the previous KeyValuePair was retrieved successfully.)But this isn't going to be efficient at all.
If feasible, consider using a
SortedList<TKey, TValue>
instead (obviously, this may not be possible if you can't take its slower inserts and deletes). This collection supports efficient key and value-retrieval by ordered index since it is implemented as a growable array. Then your query becomes as simple as:IndexOfKey
runs a binary search on the keys-list, running inO(log n)
time. Everything else should run in constant time, meaning the entire operation should run in logarithmic time.Otherwise, you'll have to implement yourself / find a BST collection that does expose predecessors / successors.
我也在寻找这个问题的答案,我认为比这里所有答案更好的解决方案是使用
TreeDictionary
来自TreeDictionary
dk/research/c5/index.html" rel="noreferrer">C5 集合 (GitHub/NuGet),这是红黑树的实现。它具有
Predecessor
/TryPredecessor
和WeakPredessor
/TryWeakPredecessor
方法(以及后继者的等效方法),它们的作用完全一样你想要什么。例如:
I was also looking for an answer to this problem, and I thought a better solution than all of the answers here is to use the
TreeDictionary<K, V>
from the C5 Collections (GitHub/NuGet), which is an implementation of a red-black tree.It has
Predecessor
/TryPredecessor
andWeakPredessor
/TryWeakPredecessor
methods (as well as equivalent methods for successors) which does exactly what you want.For example:
我猜你可以循环遍历字典并跟踪值。像这样:
然而,这是一个非常奇怪的操作。您需要它的事实可能表明您的设计存在问题。
You could loop through the dictionary and keep track of values, I guess. Something like this:
However, this is a pretty odd operation to require. The fact that you need it might be pointing at a problem with your design.
Dictionary
未排序,因此某些项目没有先前内容。相反,您可以使用SortedDictionary
。编辑:抱歉我只看了标题哈哈。
如果您必须使用 LINQ:
Dictionary<TKey,TValue>
is unsorted, so there is no previous thing for some item. Instead you can useSortedDictionary<TKey,TValue>
.EDIT: Sorry I read the title only LOL.
If you have to use LINQ:
如果是这样的话,我更愿意使用 linq...尝试一下它肯定会起作用
I would prefer to use linq if that's the case... try this it will surely work
这个怎么样?虽然我还没有测试过它,但应该给出一些东西来开始朝这个方向思考。希望有帮助。
测试其他条件,例如 if (reqIndex != -1) 等。
How about this? I havent tested it though, but should give something to start think in this direction. Hope it helps.
test for other conditions like if (reqIndex != -1) etc..