2017-08-27 11 views
0

プログラムが正常に動作しているように見えますが、最終的なアレイの開発と表示に時間がかかります。 1から45までの45個の要素を持つ必要がありますが、重複のないランダムな順序で生成されます。c#配列タイムアウトエラー

using System; 

    namespace RandomArray 
    { 
     public class RandomArrayNoDuplicates 
     { 
      static Random rng = new Random(); 
      static int size = 45; 
      static void Main() 
      { 
       int [] array = InitializeArrayWithNoDuplicates(size); 
       DisplayArray(array); 
       Console.ReadLine(); 
      } 


      /// <summary> 
      /// Creates an array with each element a unique integer 
      /// between 1 and 45 inclusively. 
      /// </summary> 
      /// <param name="size"> length of the returned array < 45 
      /// </param> 
      /// <returns>an array of length "size" and each element is 
      /// a unique integer between 1 and 45 inclusive </returns> 
      public static int[] InitializeArrayWithNoDuplicates(int size) 
      { 
       int[] arr = new int[size]; 

       for (int i = 0; i < size; i++) 
       { 
        int number = rng.Next(1, size + 1); 
        arr[i] = number; 
        if (i > 0) 
        { 
         for (int j = 0; j <= i; j++) 
         { 
          if (arr[j] == arr[i]) 
          { 

           i = i - 1; 

          } 
          else if (arr[i] != arr[j]) 
          { 
           arr[i] = number; 
          } 
         } 
        } 
       } 
       return arr; 
      } 
      public static void DisplayArray(int[] arr) 
      { 
       for (int x = 0; x < size; x++) 
       { 
        Console.WriteLine(arr[x]); 
       } 
      } 
     } 
    } 

配列内の各要素が生成された後で重複をチェックするには、要素をチェックする必要があります。これにアプローチするためのヒント

+3

数字が1〜45の配列から始めてスクランブルしてみませんか? –

+0

各番号をランダムに生成し、それを配列に追加する必要があります。 – PotatoFries

+0

@PotatoFries - なぜそれを言うのですか?それは 'サマリー'には言わない。 – Enigmativity

答えて

0

すでに配列にある数字が多いほど、すでに複製されている可能性が高くなります。最後の数字では、文字通り重複を得る機会は44/45です。そして、最悪の場合、44個の要素すべてをチェックして、重複を見つける必要があります。それはより多くの配列要素で悪化するだけです。

私はレオナルドアドバイスを繰り返すことができます:必要な数の配列を作成します。その後、その数字の順序をスクランブルします。私はそれを "宝くじの問題"と呼び、それが最も直感的なので、通常は2つのList(int)を使用します。私はそれをいくらか頻繁に書くためにいくつかのサンプルコードを見つけることができるはずです。

私はこの簡単なモックアップコードをメモ帳++に作成しました。長さを混ぜ合わせて、数を数えるか、または混乱させるかもしれませんが、あなたは要点を得るべきです。私は願っています:

List<int> input = new List<int>(); 
 
List<int> output; 
 

 
//Initialise Input 
 
for(int i = 0; i < 45; i++) 
 
    input[i]=i; 
 
    
 
//Shuffle the array into output 
 
random rng = new Random(); 
 

 
output = new List<int>(input.Lenght); 
 

 
for(; input.Lenght > 0;){ 
 
    int index = rng.NextInt(input.Lenght); 
 
    int value = input(index); 
 
    input.remove(index); 
 
    
 
    output.add(value); 
 
} 
 

 
//output is a fully randomized version of input now
私はもともとJavaでこのコードではなかった、取り外しここで、()ループの内側に1つのライナーを作る削除要素を返すの素敵な性質を持っています。

0

はい、すべて同意します。ランダム配列を生成するのは、ソートされた配列をスクランブリングするよりもはるかにコストがかかります。したがって、スクランブリングオプションを取る必要があります。この点で

は、このリンクBest way to randomize an array with .NET

0

あなたはむしろスクランブルよりも、ランダムでこれを行うことができますを確認してください、しかし、あなたのロジックは、障害があります。私の例では、すべての可能な数字とboolを持つ配列を作成します。最初はfalseです。私が数字を使うたびに、私は真実に慣れました。次に、ランダムの範囲を1つ減らして、使用していないn番目の値を自分の数値配列から取り出します。最後に、最後の値はランダムではなく、最後に使用可能な数値に過ぎません。

もう1つの点は、ランダムにシードする必要があります。それ以外の場合はランダムではありません。

コードは次のようになります。

namespace RandomArray 
{ 
    class RandomArrayNoDuplicates 
    { 
     static Random rng = new Random(DateTime.Now.Millisecond); 
     static int size = 45; 

     static void Main(string[] args) 
     { 
      int[] array = InitializeArrayWithNoDuplicates(size); 
      DisplayArray(array); 
      Console.ReadLine(); 
     } 
     /// <summary> 
     /// Creates an array with each element a unique integer 
     /// between 1 and 45 inclusively. 
     /// </summary> 
     /// <param name="size"> length of the returned array < 45 
     /// </param> 
     /// <returns>an array of length "size" and each element is 
     /// a unique integer between 1 and 45 inclusive </returns> 
     public static int[] InitializeArrayWithNoDuplicates(int size) 
     { 
      int[] allNos = new int[size]; 
      bool[] used = new bool[size]; 

      for (int i = 0; i < size; i++) 
      { 
       allNos[i] = i + 1; 
       used[i] = false; 
      } 

      int[] arr = new int[size]; 
      int max = size; 

      for (int i = 0; i < size - 1; i++) 
      { 
       int number = rng.Next(0, max); 
       int ptr = 0; 
       for (int j = 0; j < size; j++) 
       { 
        if (used[j]) 
        { 
         ptr++; 
        } 
        else 
        { 
         if (j == number + ptr) 
         { 
          break; 
         } 
        } 
       } 
       arr[i] = allNos[number + ptr]; 
       used[number + ptr] = true; 
       max--; 
      } 
      for (int i = 0; i < size; i++) 
      { 
       if (used[i] == false) 
       { 
        arr[size - 1] = allNos[i]; 
        break; 
       } 
      } 

      return arr; 
     } 
     public static void DisplayArray(int[] arr) 
     { 
      for (int x = 0; x < size; x++) 
      { 
       Console.WriteLine(arr[x]); 
      } 
     } 
    } 
} 
0

ありがとう、私は要約でブリーフィングを見逃している必要があります。あまりにもまっすぐ前方に配列を生成しようとすると、各整数の後に1/45の確率で配列を生成しようとしています。私は最後に配列をスクランブルすることができるはずです。