2011-10-23 23 views
1

好的,這應該是有趣的。找到第一個可用的長列表<long>

讓我們假設我有以下代碼:

在這個例子中,第一個可用的數目將是2

List<long> myList = new List<long>(){0,1,10,3};

在這個例子中,第一個可用的數目將是 '4'。

List<long> myList = new List<long>(){0,1,2,3};

有什麼想法嗎?

+0

千萬的數字總是從0開始?你打算修改清單並在稍後詢問第一個可用號碼嗎? – svick

+0

數字將始終從零開始,並且列表將在稍後進行修改。 – Dementic

回答

5

那麼「可用」是指「列表中尚不存在的最低非負數」?

我會忍不住寫類似:

HashSet<long> existing = new HashSet<long>(list); 
for (long x = 0; x < long.MaxValue; x++) 
{ 
    if (!existing.Contains(x)) 
    { 
     return x; 
    } 
} 
throw new InvalidOperationException("Somehow the list is enormous..."); 

編輯:另外,您也可以對列表進行排序,然後找到的第一個值,其中指數是不一樣的價值...

var ordered = list.OrderBy(x => x); 
var differences = ordered.Select((value, index) => new { value, index }) 
         .Where(pair => pair.value != pair.index) 
         .Select(pair => (int?) pair.index); 
var firstDifference = differences.FirstOrDefault(); 
long nextAvailable = firstDifference ?? list.Count; 

最後一行是採取其中的列表是連續的從0的情況照顧另一種方法是:

var nextAvailable = list.Concat(new[] { long.MaxValue }) 
         .OrderBy(x => x) 
         .Select((value, index) => new { value, index }) 
         .Where(pair => pair.value != pair.index) 
         .Select(pair => pair.index) 
         .First(); 

只要列表中不包含long.MaxValue + 1元素,這應該沒有問題,但在當前版本的.NET中不能使用它。 (這是一個很大的內存...)說實話,這已經有問題,當它超越了由於Select部分服用int指數int.MaxValue元素...

+0

你的第二個建議在最後一行有錯誤,'''在這種情況下不能應用。 – Dementic

+0

@Dementic:修正,謝謝 - 我對錯誤的表達式使用'FirstOrDefault'。 –

+0

最後我用了你的第三種方法,因爲我只是喜歡Lambda Linq。 – Dementic

2
list.Sort(); 

var range = Enumerable.Range(list.First(), list.Last()- list.First()); 

var number = range.Except(list).FirstOrDefault(); 
相關問題