2009-10-20 57 views
3

我知道C#有Random類,可能在LINQ中有幾個類來做到這一點,但是如果我要編寫自己的代碼來從集合中隨機選擇一個項目而不使用任何內置的.NET對象,這將如何完成?設計一個自定義的隨機類

我似乎無法指定所需的邏輯 - 如何告訴系統何時停止迭代並隨機選擇當前值?

編輯:這是一個假設的問題。這與生產編碼問題無關。我只是好奇。

謝謝

+0

爲什麼你不想使用任何.NET對象?他們真的很有用。 :) – 2009-10-20 21:29:42

回答

0

你需要使用種子,這是由計算機本身提供的半隨機的東西。 也許使用非常精細的分辨率時間,並在調用方法時使用最後幾個微秒。這應該足夠隨機生成從00到99的任何東西,然後你可以從那裏去。

+0

這完全沒有必要; C#的Random類已經做了這個或類似的東西。如果您要編寫代碼來實現這種效果,然後將種子饋入Random類,那麼您的代碼將完全是多餘的。 – Timwi 2009-11-07 11:50:34

+1

我知道.NET有一個隨機類,但他似乎問他怎麼可以寫他自己的隨機類... – Matt 2009-11-07 21:22:09

0

這聽起來像你的問題不是在計算一個隨機數,而是在如何使用該隨機數從列表中選擇一個項目。假設你可以以某種方式創建一個隨機數,你所需要做的就是用它作爲列表索引器的參數。

int index = customRandomGenerator.Next(); 
var selection = items[index]; 

假設你有關於通過列表迭代前提是正確的(或收集不具有索引),那麼你可以這樣做:

int index = customRandomGenerator.Next(); 
Item selection = null; 
for (int i = 0; i < items.Length; i++) 
{ 
    if (i == index) 
    { 
    selection = items[i]; 
    break; 
    } 
} 
0

唯一真正的「保密性強」 .Net框架中的隨機數生成器位於System.Cryptography.RandomNumberGenerator中 - 通過Reflector運行以查看它的作用?看看你的問題,你將需要一個知道集合的計數,否則你可能永遠不會檢索一個項目 - 你需要指定一個開始和結束的值來從隨機數中繪製隨機數 - 隨機類將工作得最好 - 通過反射器彈出。

4

從集合中選擇一個隨機元素可以按如下方式完成。

Random r = new Random(); 
int randomIndex = r.Next(0, myCollection.Size -1); 
var randomCollectionItem = myCollection[randomIndex]; 

除非你有一個很好的理由,寫自己的隨機數發生器是沒有必要的。

+0

這正是它應該如何做。 – Timwi 2009-11-07 11:51:27

0

嗯,我從來沒有想過實現我自己,因爲它似乎是重新發明輪子,但你可能有這樣的維基百科的文章一看,希望它可以幫助你做你想做的

Random Number Generator

2

有許多pseudo-random number generators。它們並不是真正的隨機性,但它們的質量不同,它們的統計特性和順​​序特性以及它們適用的目的不同。

這很大程度上取決於「你是多麼隨意需要它」。如果它只是需要「看起來是隨機的,以人類的」,簡單的生成器看起來像:

rnd = seed; // some starting value 
rnd = (a * rnd + b) % c; // next value 
... 

對於A,B的精心挑選的價值觀,cthese發電機都OK了簡單的統計檢驗。這些you find here的詳細討論和常見值。


一個有趣的方法是收集儘可能多的「外部」數據越好 - 按鍵之間的時間一樣,鼠標移動磁盤的讀取時間等 - ,並使用其累積隨機性時丟棄依賴的算法。儘管這在數學上非常棘手(IIRC不久前基於其中一種關鍵攻擊並不像想象那樣隨機)。


只有極少數特殊的應用程序使用一個真正的隨機外部硬件源 - 一開開關輸入放大器和放射性衰變之間的任何東西。

3

我對你的建議是不要做。無論您認爲自己不希望使用內置庫的原因是什麼,我都很確定您誤解了某些內容。請回到繪圖板。

以上所有的建議在技術上都是準確的,但有點像將化學教科書送給想要改進自己的汽油用於汽車的人。