2012-03-19 19 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; 
} 

ランダムための番号を再生している場合アルゴリズム、なぜ彼らは再帰を通過していますか?なぜこれは無限ループにならないのですか?

私は、デッキのシャッフルやトップからのカードの引き出しに似た、これに対する良い解決策を見つけました。オリジナルの並べ替えられた配列を作成するのは簡単ですが、どのようにシャッフルされているのか分かりません。あなたが障害

+0

スレッドセーフではありません、[範囲内でNを生成し、ランダムでユニークな番号]のところで –

+0

可能複製(http://stackoverflow.com:次に、あなただけの描いた番号を削除するList.RemoveAtを使用/ questions/4299138/generate-n-random-and-unique-numbers-within-a-range) –

+0

これは無制限であるため、これを行うのは悪い方法です。それが終了するという保証はありません。 –

答えて

9

C#で配列あなたは戻り値で何もしていない

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

を参照してくださいするにはどうすればよいです - あなたが不運であれば、あなたは

x = Unique8(rndm, num8); 
+1

また、Unique8(rndm、num8)を返す –

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<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

+0

@sji:いいえ、そうではありません。使用したアイテムをリストから削除して、再度アイテムを取得しないようにする必要があります。 –