2012-01-29 19 views
1

0から20までの10の無作為でない反復数を持つ典型的な整数の塗りつぶし配列を作成する必要があります。また、これを修正して、0から20までの乱数を除外する必要があります。非反復乱数配列

どうすればいいですか?

+0

この宿題はありますか? – asgs

答えて

4

まず次にshuffle()それ
そして最後の値0,...,19
とサイズ20のリストを作成する - 最初の10個の要素を含むsublist取ります。

15

次の3つの簡単な手順で行うことができます。

  1. あなたがそのリスト
  2. 使用して、そのシャッフルリストのn最初の要素をシャッフルする
  3. 使用Collections.shuffleたいすべての候補番号でリストを作成します。
4

このメソッドはあなたのために働くでしょう。方法は決定論的にするために:それは編集*

public static int[] getRandomArray(){ 
    int randomCount =10; 
    int maxRandomNumber = 21; 
    if(randomCount >maxRandomNumber){ 
     /* if randomCount is greater than maxRandomNumber 
      * it will not be possible to generate randomCount 
      * unique numbers 
      **/ 
      return null; 
    } 
    HashMap<Integer, Integer> duplicateChecker = new HashMap<Integer, Integer>(); 
    int[] arr = new int[randomCount ]; 
    int i = 0; 
    while(i<randomCount){ 
     // Generate random between 0-20, higher limit 21 is excluded 
     int random = new Random().nextInt(maxRandomNumber); 
     if(duplicateChecker.containsKey(random)==false){ 
      duplicateChecker.put(random, random); 
      arr[i]=random; 
      i++; 
     } 
    } 
    return arr; 
} 

20に0から10個のユニークな乱数を生成します。無限ループの可能性を避ける

public static int[] getRandomArray(){ 
    int randomCount =10; 
    int maxRandomNumber = 21; 
    if(randomCount >maxRandomNumber){ 
     /* if randomCount is greater than maxRandomNumber 
     * it will not be possible to generate randomCount 
     * unique numbers 
     **/ 
     return null; 
    } 
    ArrayList<Integer> arrayList = new ArrayList<Integer>(); 
    // Generate an arrayList of all Integers 
    for(int i=0;i<maxRandomNumber;i++){ 
     arrayList.add(i); 
    } 
    int[] arr = new int[randomCount ]; 
    for(int i=0;i<randomCount;i++){ 
     // Generate random between 0-20, higher limit 21 is excluded 
     int random = new Random().nextInt(arrayList.size()); 
     // Remove integer from location 'random' and assign it to arr[i] 
     arr[i]=arrayList.remove(random);   
    } 
    return arr; 
} 
+3

まあ、理論的には、これは終了する保証はありません。ランタイムは確定的ではありません。 – Mat

+0

@Mat Random.nextIntは、すべての数値のほかに一様(多かれ少なかれ)の数値を最終的に描画する必要があるため、終了します。 – Trismegistos

+0

ある時点で停止します。しかし、その点は、星の適切な位置合わせを与えられた反復の大巨星の後であるかもしれない。ランタイムは確定的ではありません。 – Mat

1

他のほとんどの応答は、解決策としてCollections.shuffleメソッドを提供しています。理論的に高速であるもう一つの方法は、以下の通りである。

最初にリストを構築することができます:

public class RandomWithoutReplacement { 
     private int [] allowableNumbers; 

     private int totalRemaining; 

     /** 
     * @param upperbound the numbers will be in the range from 0 to upperbound (exclusive). 
     */ 
     public RandomWithoutReplacement (int upperbound) { 
       allowableNumbers = new int[ upperbound ]; 
       for (int i = 0; i < upperbound; i++) { 
        allowableNumbers[i] = i; 
       } 
       totalRemaining = upperbound; 
     } 
} 

次に、我々は次の番号を取得する必要があるときに何をする必要があるかを検討することができます。

1)別の番号を要求するときは、利用可能な一意の番号から一意に選択する必要があります。

2)一度選択すると、再び繰り返されてはなりません。

私たちができることは次のとおりです。 まず、allowableNumbersアレイからランダムに数字を選択します。 次に、配列から削除します。 次に、配列の最後にある番号を削除し、戻す番号の位置に配置します。 これは、私たちが置いた2つの条件すべてを保証します。

 public int nextRandom() { 
      //Get a random index 
      int nextIndex = (int) (Math.random() * totalRemaining); 
      //Get the value at that index 
      int toReturn = allowableNumbers [ nextIndex ]; 
      //Find the last value 
      int lastValue = allowableNumbers [ totalRemaining - 1 ]; 
      //Replace the one at the random index with the last one 
      allowableNumbers[ nextIndex ] = lastValue; 
      //Forget about the last one 
      totalRemaining -- ; 

      return toReturn; 
     } 

これで、あなたの機能はほぼ完了です。

私は念のためにカップルより多くのものを追加します。

 public boolean hasNext() { 
      return totalRemaining > 0; 
     } 

そして、実際の関数の先頭に:それはあるべき

 public int nextRandom() { 
      if (! hasNext()) 
       throw new IllegalArgumentException(); 
      // same as before... 
     } 

+0

このメソッドがCollections.shuffleよりもどのように高速か分かりません。コレクションシャッフルはexaclyと同じように動作しますが、配列をシャッフルした後にtotalRemaining変数を取り除く可能性があるため、メモリの使用量が少なくなります。あなたのクラスはN個の配列を割り当てますが、ユーザはそれらの配列を必要としますので、N個の配列を割り当てます。そのため、メモリ制約はCollections.shuffleが動作するかどうかを少なくとも2 * Nにします。メモリ - サイズNの配列はクラスにあるものと同じくらいの数の追加ローカル変数を加えています。 – Trismegistos

+0

[Collection.shuffle](http://docs.oracle.com/javase/6/docs/api/java/util/Collections.html#shuffle(java.util.List))のドキュメントを読むと、シャッフルするのに線形時間がかかることがわかります。これは、構築に必要な線形時間を追加します。さらに、メモリ使用量が少なくとも2 * Nであることは間違っています。実際に** **多くても** 2 * Nです。これは、ユーザーがN個の乱数を必要とするからです。ユーザが小さなランダムなサブセットを望むなら、私のアプローチはより良いと思います。ユーザが大きなランダムなサブセットを望むなら、Collections.shuffleの方が良いでしょう。 –

+0

私はローカル変数を数えなかったので、それは2 * N * sizeof(int)バイトです。 – Trismegistos

0

私は、数字の配列を2倍のランダムな場所に格納している私の解決策を投稿しないように助けてくれませんでした。その後、結果の配列に圧縮します。

int [] myRandomSet = generateNumbers(20、10);

...

public int[] generateNumbers(int range, int arrayLenght){ 
    int tempArray[]; 
    int resultArray[]; 
    int doubleLocations; 
    Random generator = new Random(); 

    doubleLocations = range * 2; 
    tempArray = new int[doubleLocations]; 
    resultArray = new int[arrayLenght]; 

    for (int i=1; i<=range; i++){ 
     if (i != 5 && i != 13){ //exclude some numbers 
      do{ 
       r = generator.nextInt(doubleLocations); 
      }while(tempArray[r]!=0); 
      tempArray[r] = i; //enter the next number from the range into a random position 
     } 
    } 

    int k = 0; 
    for (int i=0; i<(doubleLocations); i++){ 
     if(tempArray[i] != 0){ 
      resultArray[k] = tempArray[i]; //compact temp array 
      k++; 
      if (k == arrayLenght) break; 
     } 
    } 

    return resultArray; 
} 
2

20件までの数字の配列リストを作るについては何、および各乱数コールの後にリストから、配列に番号を削除します。

Random r = new Random(); 
int[] myArray = new int[10]; 
ArrayList<Integer> numsToChoose = new ArrayList<Integer>(); 

int counter = 0; 

for(int i = 0; i < 21; i++) 
{ 
    numsToChoose.add(i); 
} 

while(numsToChoose.size() > 11) 
{ 
    myArray[counter] = numsToChoose.remove(r.nextInt(numsToChoose.size())); 
    counter++; 
} 

それだけでループを10回する必要があることの方法、しかし私は間違っている可能性があります。 希望する

EDIT:これを修正して特定の数値を除外するには、その数値をパラメータとして含む配列を取り、それを前にarraylistから削除してループするメソッドが必要ですあなたは乱数を生成します。