2012-03-19 44 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