2013-02-18 12 views
6

乱数を生成したいが、それらをexcludeRows配列にしたくない。ここに私のコードです。特定の値以外の乱数を生成する

public int generateRandom(int start, int end, ArrayList<Integer> excludeRows) { 
    Random rand = new Random(); 
    int range = end - start +1 - excludeRows.size(); 
    int random = rand.nextInt(range) + 1; 

    for(int i = 0; i < exclude.size(); i++) { 
     if(excludeRows.get(i) > random) { 
      return random; 
     } 
     random++; 
    } 

    return random; 
} 

私はwhileループでは、この機能を使用し、各反復の間に、私はexcludeRowsに新しい値を追加します。 時々、excludeRowsに属する番号を返します。どうしたの?

+2

「excludeRows」と「exclude」は同じものですか? – Vlad

+0

はい、名前を変更するのを忘れました – user2081119

+0

この関数では、 'excludeRows'に数値を追加しません。それで私の解決策では、私はそれをやっていません。私はそれを補足する必要がありますか? – qben

答えて

5
if(!exclude.contains(random)) 
    return random; 

はそれが意志このたびをお試しくださいが除外されていない値を返します。

+1

それは動作します!どうもありがとう! :) – user2081119

+0

@ user2081119 upvoteして受け入れることができます。ありがとう –

+0

@ user2081119私の解決策を見てみることをお勧めします。私が思うと役に立ついくつかの発言があります。 – qben

2

かを確認:

for(int i = 0; i < exclude.size(); i++) { 
    if(exclude.get(i) > random) { 
     return random; 
    } 

をし、唯一の最初の方が大きい場合は、値を返します。 excludeはソートされていますか?あなたがif(exclude.contains(random))または次のアルゴリズムを使用することができます

(end-start)は、合理的な数であり、あなたはすべての許容数のリストを作成し、このリストのサイズにランダムに使用してランダムに選択することができ、ほぼすべての値を必要とする

場合インデックスとしての値。リストから不要な番号を削除し、別のランダムなインデックスを取得します。

+2

私は彼がexcludeがソートされているという事実に頼っていると思います。 –

6

いくつかの間違いがあると思います。

1)範囲はend-start + 1である必要があります。
2)本当に乱数を(コンピューター上でできるだけ「ランダム」として)使用したい場合は、ただちに使用可能な次の番号を取得するべきではありません。この場合、乱数は除外された数の密度/頻度の特性を持つためです。

public int generateRandom(int start, int end, ArrayList<Integer> excludeRows) { 
    Random rand = new Random(); 
    int range = end - start + 1; 
    int random; 

    boolean success = false; 
    while(!success) { 
     random = rand.nextInt(range) + 1; 
     for(Integer i: excludeRows) { 
      if(i == random) { 
       break; 
      } else if (i > random) { 
       success = true; 
       break; 
      } 
     } 
    } 
    return random; 
} 

私のコードが改善した(が、同様に、いくつかの発言があります注意してください)することができAchintya Jhaはの答えを

UPDATE:

public int generateRandom(int start, int end, ArrayList<Integer> excludeRows) { 
    Random rand = new Random(); 
    int range = end - start + 1; 

    int random = rand.nextInt(range) + 1; 
    while(excludeRows.contains(random)) { 
     random = rand.nextInt(range) + 1; 
    } 

    return random; 
} 
+1

ありがとう!素敵な解決策 – user2081119

0

実際には、whileループでcontains(random)を使用する必要はありません。

質問を簡略化するため、値が1つしか除外されていないとどうなるかを見てみましょう。結果を2に分割することができます。可能な値の数はrange-1です。乱数が除外された値より小さい場合は、それを返します。それ以外の場合は、1を追加できます。

複数の除外値の場合、結果セットをsize+1に分割できます。ここで、sizeは除外値の数です。可能な値の数はrange-sizeです。次に、昇順に値を除外して並べ替えます。乱数が除外値からiを引いた値よりも小さい場合は、乱数を返します。iを返します。ここで、iは除外値のインデックスです。

public int generateRandomNumberWithExcepts(int start, int end, List<Integer> excepts) { 
    int size = excepts.size(); 
    int range = end - start + 1 - size; 
    int randNum = random.nextInt(range) + start; 
    excepts.sort(null); // sort excluding values in ascending order 
    int i=0; 
    for(int except : excepts) { 
     if(randNum < except-i){ 
      return randNum + i; 
     } 
     i++; 
    } 
    return randNum + i; 
}