내가 SortedDictionary<int, object>
인 경우 현재 사용되지 않는 가장 낮은 키를 찾는 가장 빠른 방법은 무엇입니까? 분명히 우리는 0->int.MaxValue
에서 카운터 i를 반복 할 수 있고 !Keys.Contains(i)
이면 탈출 할 수 있습니다. 그러나 운이 좋고 첫 번째 예비 키가 키 시퀀스에서 일찍 일어나지 않으면 매우 느릴 수 있습니다. 어쩌면 다른 .NET 클래스도 이미이 작업을 수행합니까?SortedDictionary에서 처음 사용되지 않는 키를 빠르게 찾으려면 어떻게해야합니까?
답변
그렇다면 올바르게 이해하면 키는 0
에서 int.MaxValue
사이 일 수 있습니다. 이 경우, 키의 순서에서 첫 번째 "구멍"을 찾아야합니다.
이
효율적으로 작업을 수행해야합니다 내가 전제 조건이 유효한지 확인하기 위해 검사의 몇 가지를 추가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;
}
}
.
나는이 방법에 대한 성능 트로피의 모든 종류의 주장 아니지만, 나는 그것이 당신의 목표를 성취하기 위해 어떻게든지 간다 생각 :이 경우
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();
전자 = 3, 의도 한대로. 그래도 더 나은 해결책이있을 것으로 기대합니다.
Nice . 꽤 효율적이라고 생각합니다. –
작은 사전에는 괜찮을 것이라고 확신합니다. 그것이 어떻게 확장 될지, 나는 모른다. – Jason
대신 (그들은 분류되어 있습니다) 가장 낮은에서 시작 사용 키를 반복 0
에서 사용되지 않는 키의 시작을 검색하지 마십시오.
첫 번째 값이 0보다 크면 0이 가장 낮게 사용되지 않습니다.
두 개의 키 사이에 간격이 있으면 더 낮은 +1이 검색 한 것입니다.
왜 키를 이진 검색하지 않습니까?
ElementAt() 메서드를 사용하여 인덱스에서 키 값을 식별 할 수 있습니다. 키 값이 인덱스보다 큰 경우 왼쪽 하위 사전을 검색하거나 오른쪽을 선택하고 인덱스에서 인덱스의 값과 인덱스의 첫 번째 차이를 관찰 할 인덱스를 찾을 때까지 계속 이동하십시오.
이것은 O (log n)을 가지며 다른 것들을 상쇄합니다. 잘 했어. – DrKoch
아니요. 'ElementAt'는 각 호출 @DrKoch에서 사전을 열거합니다. 이것은이 해를 O (n²)와 비슷하게 만듭니다. 'SortedDictionary'가'IList
흠. 좋은 지적 @ 루카스,하지만 우리가 intmax/2로 시작하는 열쇠를 찾으면, 아마도 이진 검색 도움이 될 것입니다 왼쪽 그리고 어쩌면 그때 왼쪽으로 가득 차 있다면 오른쪽으로 갈까? –
사전의 가능한 인구에 대해 아는 것이 있습니까? 얼마나 많은 키가 존재할 것입니까? –
물론 - 내가 거대한 사전을 가질 확률이 높지 않기 때문에 내가 제안한, clunky 한 방식으로 또는 실제로 여분의 키를 추적하는 것은 기쁠 것이다. 그러나 현명한 방법은 멋질 것이다. :) –