2012-12-25 279 views
3

我想隨機取50個數字,以便在隨機方法中不得有重複。在隨機生成50個隨機數中使用隨機數#

下面是到目前爲止我的代碼:

private void settext() 
{  
    int i; 
    Queue <int> qe= new Queue<int>(50); 
    Random rm= new Random(); 
    for (int g = 0; g < 50; g++) 
    { 
     i = rm.Next(1, 50); 
     if (!qe.Contains(i)) 
     { 
       qe.Enqueue(i); 
     }     
    } 
} 
+2

它有什麼問題?它會拋出異常還是不能正常工作? – 3aw5TZetdf

+0

你的代碼有什麼問題? –

+2

這是dejavu嗎? –

回答

1

唯一的問題與您的代碼是,如果重複被發現,你還在遞增循環,並在您的隊列沒有得到所有的值(50)。您可以使用while循環,並且只在找到非重複值時增加索引。

int index=0; 
int i; 
Queue<int> qe = new Queue<int>(50); 
Random rm = new Random(); 
while(index< 50) 
{ 
    i = rm.Next(1, 51); //to get from 1 to 50 
    if (!qe.Contains(i)) //to check for duplicate 
    { 
     qe.Enqueue(i); 
     ++index; 
    } 

} 

以上將產生50個獨特的隨機數字,如果你想利用20個號碼從他們則:

var numbers = qe.Take(20); 
+0

+1:只有可能'只有'qe.Enqueue(i);'然後'++索引;' – horgh

+0

@KonstantinVasilcov謝謝指出 –

+2

downvote的原因? –

1

你強迫它找到50個不同的數字,而只允許它來生成我想,它們有49種可能的範圍之外。改爲嘗試rm.Next(50) + 1

1

如何使用Linq?

private static Random rand = new Random(); 

var twentyUniqueNumbers = RandomNumberStream().Distinct().Take(20); 

IEnumerable<int> RandomNumberStream() 
{ 
    yield return rand.Next(1,50); 
} 

或者更好的是,創建50個號碼的列表,隨機播放再取20 ......

var twentyUniqueNumbers = Enumerable.Range(0,50) 
            .OrderBy(s => rand.Next()); 
            .Take(20); 

這會得到更可預測的性能。

+0

我不會推薦使用'OrderBy'。是的,它可能會工作,但它效率低下,沒有任何好處,也不能表明你實際想要做什麼,海事組織。有很多更好的洗牌方式。 –

+0

@JonSkeet在這種情況下是可以的,但你是正確的... http://stackoverflow.com/questions/1287567/is-using-random-and-orderby-a-good-shuffle-algorithm – ColinE

5

不是循環,直到找到一個尚未使用的數字,我建議只創建一個包含50個可能數字的列表(或數組),並對其進行混洗。然後你可以採取他們想要的許多。

Stack Overflow上有很多混洗問題,比如this one

這樣做的優點是性能是完全可以預測和線性 - 而如果你把所有50個號碼的開出50,在結束時,你將必須繼續產生隨機數,直到你發生得到最後一。 50也不是太差,但想象一下,如果你有成千上萬的數字...

(還要注意,你現有的代碼不會在任何地方使用數字20,如果你試圖剛剛產生20個號碼...)

0

按照你的邏輯可能是簡單的寫:

var results = new HashSet<int>(); 
var random = new Random(); 
while (results.Count < 20) 
{ 
    results.Add(random.Next(1, 50)); 
}; 

有沒有必要檢查號已被添加到HashSet中 爲每一個數字將只添加一次...

然而......這只是一個快速修復,可以幫助你理解你正在嘗試解決的問題(基本上是教室的例子) 但是你應該真的接受Jon Skeet提供的建議,因爲你不知道實際執行上面的代碼需要多長時間。

需要注意的另一件事是,您正在使用Queue類,它的目的是像FIFO緩衝區一樣使用......這並不適用於您的問題。