2012-03-19 32 views
1

我意識到使用隨機不會產生真正的隨機數,但我不明白爲什麼這個代碼不應該阻止重複。我們的目標是從之間(不包括)0和44獲得8個唯一的號碼有沒有運行代碼的任何錯誤,但確實會發生重複:對非重複隨機數使用遞歸循環和整數數組

//Loop Begins Within Main 
for (int i = 0; i < 8; i++) 
{ 
    //Begins Recursion 
    int x = Unique8(rndm, num8); 
    num8[i] = x; 
} 

//Recursion Takes Place Outside of the Main with Static Declarations 
static Random rndm = new Random(); 
static int[] num8 = new int[8]; 

static int Unique8 (Random rndm, int[] num8) 
{ 
    int x = rndm.Next(1, 43); 

    //Seeks if Number is Repeated 
    if (num8.Contains(x)) 
    { 
     //If So, Recursion Takes Place 
     Unique8(rndm, num8); 
    } 

    //Returns Value to Original Loop to be Assigned to Array 
    return x; 
} 

如果隨機是由於再生的數算法,爲什麼他們通過遞歸?爲什麼這不會成爲一個無限循環?

我已經找到了一個很好的解決方案,類似於洗牌的甲板和從頂部的繪圖卡。創建原始的排序數組很容易,但我不明白它是如何「洗牌」的。你怎麼亂用C#

+0

的[生成N個隨機和唯一編號的範圍內] BTW – 2012-03-19 13:19:40

+0

可能重複(http://stackoverflow.com/questions/4299138 /在一個範圍內產生n個隨機數和唯一數) – 2012-03-19 13:20:02

+0

這是一個不好的方法,因爲它是無界的。無法保證它永遠不會終止。 – 2012-03-19 13:39:23

回答

9

數組見

//If So, Recursion Takes Place 
Unique8(rndm, num8); 

你不和返回值做任何事情 - 你 應該 可如果你很不幸更改爲

x = Unique8(rndm, num8); 
+1

甚至返回Unique8(rndm,num8) – 2012-03-19 13:35:02

2

,您的代碼可能會導致stackoverflow。這是另一種使用混洗獲得8個唯一編號的方法。

int[] array = new int[43]; 
for (int i = 0; i < array.Length; i++) array[i] = i+1; 

FisherYatesShuffle(array); 

int[] newArray = array.Take(8).ToArray(); 

public static void FisherYatesShuffle<T>(T[] array) 
{ 
    Random r = new Random(); 
    for (int i = array.Length - 1; i > 0; i--) 
    { 
     int j = r.Next(0, i + 1); 
     T temp = array[j]; 
     array[j] = array[i]; 
     array[i] = temp; 
    } 
} 
0

的一種方法是使用費雪耶茨洗牌作爲L.B已經發布。我過去做過的另一種方法是用所有可能的值填充一個列表,然後通過生成一個介於0和列表計數之間的隨機數從該列表中隨機抽取。然後使用List.RemoveAt刪除自己剛畫數:是不是線程安全的

List<int> myList = new List<int>(43); 
for (int i = 0; i < array.Length; i++) myList.Add(i+1); 


for (int j = 0; j < 8; j++) 
{ 
    int idx = rndm.Next(myList.Count); 
    num8[i] = myList[idx]; 
    myList.RemoveAt(idx); 
} 
+0

這不是基本上和'return rndm.Next(myList.Count)'一樣嗎? – sji 2012-03-19 14:34:09

+0

@sji:不,它沒有。您必須從列表中刪除已使用的項目,以確保您不再獲取它們。 – 2012-03-19 14:53:44