私はランダムなint数を取るための次のコードを持っています
for (int i=1;i<=5;i++) {
int rand= new Random().nextInt(10);
Log.d("Ramdom number", String.valueOf(rand));
}
問題は、乱数を繰り返さないようにすることです。つまり、このコードを実行すると、5つの数字が表示されますが、そのうちの2つは少なくとも繰り返されます。何かアドバイス?
選択する数値の範囲が小さい場合、これでうまくいくはずです。
ArrayList<Integer> numbers = new ArrayList<Integer>();
for (int i = 0; i < 20; ++i) {
numbers.add(i);
}
Collections.shuffle(numbers);
for (int i = 0; i < 5; ++i) {
Log.d("Random number", numbers.get(i).toString());
}
問題は、ループ内にランダムオブジェクトを作成していることです。この場合のように、ループが「タイト」である場合、Randomオブジェクトには同じ値がシードされます。ランダムオブジェクトの初期化をループの外に移動すると、うまくいくはずです。
Random r = new Random();
for (int i=1;i<=5;i++) {
int rand= r.nextInt(10)
Log.d("Ramdom number", String.valueOf(rand));
}
編集:
これはうまくいくはずです(少なくとも私にとってはうまくいきました)
public static Integer[] getRangedInt(int maxRange, int numCount)
{
if (maxRange < numCount)
{
throw new Exception("maxRange cannot be smaller than numCount");
}
Set<Integer set = new HashSet<Integer>();
Random r = new Random();
while (Set.size() < numCount)
{
int random = r.nextInt(maxRange);
while (!set.add(random))
{
random = r.nextInt(maxRange);
}
}
return set.toArray(new Integer[set.size()]);
}
final int maxnumbers = 5;
final int maxvalue = 10;
final Random generator = new Random();
Set<Integer> numbers = new HashSet<Integer>();
while(numbers.size() < maxnumbers){
numbers.add(random.nextInt(maxvalue));
}
このループの後、 0 とset のmaxnumber
間に繰り返されない乱数が必要です。この方法を使用するときは、反復回数が多すぎないように注意する必要があります。つまり、10000 から 9999 個の非反復数を生成するには、おそらく長い時間がかかります。maxvalue
numbers
別のよりスケーラブルなバージョンは、数字のリストを持つことです:
List<Integer> numbers = new ArrayList<Integer>();
for(int i = 0; i<maxvalue; i++){ numbers.add(i); }
Collections.shuffle(numbers);
List<Integer> randomnums = numbers.subList(0, maxnumbers);
つまり、探しているのは乱数のリストではなく、ランダムに並べられた 30 個の数字のリストです。
1 つの方法は、すべての可能な値のリストを生成し、それらをランダムに並べ替え、必要に応じてリストの先頭から剥がすことです。ここにいくつかの擬似コードがあります:
for(int i=1; i<=30; i++) {
double r = rand();
while (null != aTreeSet.get(r)) r = rand();
aTreeSet.put(r, i);
}
whereは、おそらく 0 から 1 の間rand()
のランダムな値 (求める 1 ~ 30 ではありません) を返します。i
aTreeSet
このループは、 によって dup が返されるという万一の事態が発生した場合の悲しみを防ぎrand()
ます。
これを使用するにはaTreeSet
、ソートされた順序で値を取得します。
編集 -総解
もう 1 つの方法は、1 ~ 30 の値を生成し、それが「I have seen this」セットにまだない場合は、それを追加して値を返すことです。存在する場合は、新しい乱数を生成します。未使用の番号が見つかるまで繰り返します。これは、最後のいくつかの値については、相対的に言えばパフォーマンスが低下しています。もちろん、最近のプロセッサの 30 個の値の場合、ミリ秒単位で完了します。もしあなたの最大値が 30 ではなく 1,000 だったら、私は心配し始めます。
乱数のSETが必要だと思います。このヒントで十分です。
そうでない場合は、コメントしてください。
生成された数値の 1 つのリストを維持できます
boolean flag=false;
Vector<int> vec = new Vector<int>();
for (int i=1;i<=5;i++) {
flag=false;
int rand= r.nextInt(10);
for(int j=0;j<vec.size();j++)
{
if(vec.get(j)==rand)
{
flag=true;
break;
}
}
if(flag)
{
continue;
}
else
{
Log.d("Ramdom number", String.valueOf(rand));
vec.add(rand);
}
}
生成された数値のベクトルを維持してチェックすることができます
その番号はすでに生成されているか、新しい番号を生成します
それ以外の場合は、この番号を表示します
あなたが望むのはランダムな組み合わせです。繰り返しを避けるためにハッシュテーブルを使用してください
私の頭の上から、コードは次のようになります。
Ramdom r = new Random();
Hashtable<Integer, Integer> h = new Hashtable<Integer, Integer>();
while( h.keys().size() < 5 ) {
int i = r.nextInt(10);
h.put(i,i);
}
Integer[] k = (Integer[]) h.keySet().toArray();
この線
h.put(i,i);
繰り返される場合は値を上書きするだけなので、異なる描画された数字のみがハッシュ テーブルにエントリを持ちます。
生成した数値をセットに保存し、セットにない場合にのみ乱数を使用できます
Random r = new Random();
Set<Integer> generatedNumbers = new HashSet<Integer>();
for(int i = 1;i<=5;i++) {
int rand = r.nextInt(10)
if (!generatedNumbers.contains(rand)) {
Log.d("Ramdom number", String.valueOf(rand));
generatedNumbers.add(rand);
}
}