如果我有SortedDictionary<int, object>
,找到当前未使用的最低密钥的最快方法是什么?显然,我们可以从0-&gt; int.MaxValue
迭代一个计数器i并在!Keys.Contains(i)
时转义,但除非我们很幸运并且第一个备用键恰好在序列的早期,否则这将非常慢钥匙也许甚至一个不同的.NET类已经为我们做了这个?
答案 0 :(得分:2)
所以,如果我理解正确,那么密钥可以是0
到int.MaxValue
的任意位置。在这种情况下,你必须找到第一个&#34;洞&#34;在按键序列中。
这应该有效地完成工作:
public static int GetFirstUnusedKey<TValue>(SortedDictionary<int, TValue> dict)
{
if (dict.Comparer != Comparer<int>.Default)
throw new NotSupportedException("Unsupported comparer");
using (var enumerator = dict.GetEnumerator())
{
if (!enumerator.MoveNext())
return 0;
var nextKeyInSequence = enumerator.Current.Key + 1;
if (nextKeyInSequence < 1)
throw new InvalidOperationException("The dictionary contains keys less than 0");
if (nextKeyInSequence != 1)
return 0;
while (enumerator.MoveNext())
{
var key = enumerator.Current.Key;
if (key > nextKeyInSequence)
return nextKeyInSequence;
++nextKeyInSequence;
}
return nextKeyInSequence;
}
}
我添加了几项检查以确保前提条件有效。
答案 1 :(得分:2)
为什么不在键上进行二进制搜索?
您可以使用ElementAt()方法识别索引处的键值。如果键值大于索引,则在左子词典中搜索或选择右侧词典并继续,直到找到索引与索引值之间的第一个差异的索引。
答案 2 :(得分:0)
我并没有为这种方法申请任何表现奖杯,但我认为它在实现目标方面有所作为:
var sd = new SortedDictionary<int, object>();
sd.Add(1, 1);
sd.Add(2, 1);
sd.Add(4, 1);
sd.Add(5, 1);
var e = Enumerable.Range(1, 5).Except(sd.Keys).First();
在这种情况下,e = 3,如预期的那样。不过,我希望有更好的解决方案。
答案 3 :(得分:0)
请勿从0开始搜索未使用的密钥。
而是迭代使用过的键,从最低位开始(它们已排序)。
要么第一个是> 0,那么0是你未使用的最低值。
或两个键之间存在间隙,然后低于+ 1是您搜索的内容。