2016-11-05 10 views
-1

二次元配列に一意の乱数(行/列の異なる数字)を埋め込むにはどうすればよいですか?2次元配列に一意の乱数を埋め込む方法

私はすでに1次元配列のためにそれを行っている:

class Program 
{ 
    static void Main(string[] args) 
    { 
     Random r = new Random(); 

     int[] x = new int[10]; 

     for(int i = 0; i < x.Length; i++) 
     { 
      x[i] = r.Next(9); 

      for(int j = 0; j < i; j++) 
      { 
       if(x[i] == x[j]) 
       { 
        i--; 
        break; 
       } 
      } 
     } 

     for(int i = 0; i < x.Length; i++) 
     { 
      Console.WriteLine(x[i]); 
     } 

     Console.ReadKey(); 
    } 
} 

答えて

3

あなたがそれぞれの1が最善のアプローチではありません持ってまで、あなたが繰り返しRandomを使用して、任意の重複をしたくないので。理論的には、randomizerが希望の値を早期に提供しない場合、そのようなアルゴリズムは非常にの時間で実行できます。

あなたが望む値を知っていますが、それらをランダムな順序で使用したいので、通常はshuffleアルゴリズムが適しています。 シャッフルアルゴリズムを使用すると、目的の値の配列を生成し、シャッフルしてランダムな順序で取得できます。

多次元配列のための最も簡単な方法は、最初に1次元配列に必要な値をすべて入れ、シャッフルして配列を多次元配列に変換することです。 しかし、it is possibleは、多次元配列に作用するシャッフルアルゴリズムを一般化する。

コードがどのように表示されるかの例は、参照される回答に示されています。

0

これは少し宿題のようです。ここでは、そのようなint[10,10]のような2次元の整数配列に整数で(あなたのケースでは、10×10)一定の範囲をシャッフルのアイデアがあります:

using System; 
using System.Linq; 
using System.Collections; 

class MainClass { 

    public static void Main (string[] args) { 
    // table dimension (assumes a square) 
    var dim = 10; 
    var table = new int?[dim, dim]; 

    // 100 integers: 0..99 
    var queue = new Queue(Enumerable.Range(0, dim * dim).ToList<int>()); 
    var rng = new Random(); 


    int x = dim/2, y = dim/2; 

    // Acceptable shuffle? As long as the queue has anything in it, try to place the next number 
    while(queue.Count > 0) { 
     x = rng.Next(dim); // still using random, not great! :(
     y = rng.Next(dim); 

     if(table[x,y] == null) 
      table[x,y] = (int)queue.Dequeue(); 
    } 

    // print output so I know I'm not crazy 
    for(var i = 0; i < dim; i++) { 
     Console.Write("Row {0}: [", i); 
     for(var j = 0; j < dim; j++) { 
      Console.Write("{0,4}", table[i,j]); 
     } 
     Console.WriteLine("]"); 
    } 
    } 
} 

出力:

Mono C# compiler version 4.0.4.0 

Row 0: [ 55 45 38 23 88 46 7 89 0 94] 
Row 1: [ 2 92 43 51 58 67 82 90 79 17] 
Row 2: [ 29 64 16 8 50 14 1 25 26 73] 
Row 3: [ 97 37 13 20 4 75 98 80 48 12] 
Row 4: [ 33 27 42 74 95 35 57 53 96 60] 
Row 5: [ 59 86 76 40 6 11 77 49 93 61] 
Row 6: [ 5 72 9 91 68 30 39 69 99 21] 
Row 7: [ 52 31 28 34 3 81 18 62 10 71] 
Row 8: [ 66 24 44 54 56 85 84 22 47 63] 
Row 9: [ 65 36 83 41 15 19 87 78 70 32] 
0

ここでMAV年代の実装での私のショットです答え:彼は言う同様

private Random random = new Random(); 

private void Shuffle(ref int[] array) 
{ 
    int r, temp; 
    for (int i = array.Length - 1; i >= 0; i--) 
    { 
     r = random.Next(i + 1); 
     temp = array[r]; 
     array[r] = array[i]; 
     array[i] = temp; 
    } 
} 

public int[,] GetUniqueArray() 
{ 
    int[,] array = new int[10,10]; 

    int[] temp = Enumerable.Range(0, 100).ToArray(); 
    Shuffle(ref temp); 

    for (int i = 0; i < temp.Length; i++) 
    { 
     array[i/array.GetLength(0), i % array.GetLength(1)] = temp[i]; 
    } 

    return array; 
} 

は、ブルート強制的にランダムなだけでなく、ユニークである配列の内容は、配列がどのように大きなに応じて、問題を引き起こす可能性があります。多くの衝突が発生している状況に遭遇した場合、プログラムがクロールを遅らせることがありますが、まだ使用されていないものを盲目的に探している単一の配列インデックスに対して数百の乱数が生成されます。

この方法は、すでにユニークな数値が入力されている希望のサイズの配列から始め、その点から順番に並べ替えるだけです。あなたは一定のランタイムとはるかに少ない問題で望ましい結果を得ることができます。

関連する問題