配列から要素をランダムに選ぶ方法


94

整数配列からランダムに数値を選択するソリューションを探しています。

たとえば、配列がnew int[]{1,2,3}ありますが、ランダムに数値を選択するにはどうすればよいですか?


回答:


181
public static int getRandom(int[] array) {
    int rnd = new Random().nextInt(array.length);
    return array[rnd];
}

2
はい、しかしあなたはそれgeneratorがのインスタンスであることを言わなければなりませんjava.util.Random
stivlo

25
Random()関数を実行するたびに作成することはありません。ランダムジェネレーターには履歴があるはずです。そうでない場合、それは非常に予測可能です。この場合はまったく問題ありませんがarray[(int)(System.currentTimeMillis() % array.length)]、提案されたソリューションと同じくらい優れていることを述べておく必要があります。
ALF

4
@alf、それは提案された解決策ほど良くありません。new Random()以前に作成されたものとは異なるシードを持つインスタンスを作成しようとしますRandom。あなたのアプローチは、関数を短時間で2回呼び出すだけでひどく壊れるでしょう。
aioobe

1
@alfいくつかのシステムでは、次の場合、いくつかの選択肢を排除することに-ミリ秒正確なクロックはありませんgcd(array.length,clockAccuracy)!=1
ラチェットフリークを

3
この回答に反対票を投じたという通知に気づきました-誤ってクリックしたに違いありません。残念ながら、インターフェースでは元に戻すことができません(回答を編集しないと投票を変更できないと表示されています...)。それでは、クリス・デネットに謝罪します。
Peter Hanley、

13

ランダムジェネレーターを使用してランダムインデックスを生成し、そのインデックスの要素を返すことができます。

//initialization
Random generator = new Random();
int randomIndex = generator.nextInt(myArray.length);
return myArray[randomIndex];

9

ランダムな要素を複数回取得する場合は、乱数ジェネレータが1回だけ初期化されるようにする必要があります。

import java.util.Random;

public class RandArray {
    private int[] items = new int[]{1,2,3};

    private Random rand = new Random();

    public int getRandArrayElement(){
        return items[rand.nextInt(items.length)];
    }
}

予測不可能である必要があるランダムな配列要素を選択する場合は、 は、Randomではなくjava.security.SecureRandom。これにより、誰かが最後のいくつかの選択を知っている場合、次の選択を推測する利点がなくなります。

あなたがジェネリックを使用してオブジェクト配列からランダムな番号を選ぶために探している場合は、その(出典行うための方法を定義することができますのAvinash Rでの文字列配列からランダムな要素を):

import java.util.Random;

public class RandArray {
    private static Random rand = new Random();

    private static <T> T randomFrom(T... items) { 
         return items[rand.nextInt(items.length)]; 
    }
}

3

を使用java.util.Randomして、0と配列の長さの間の乱数を生成します。random_number次に、乱数を使用して整数を取得します。array[random_number]



2

あなたも使うことができます

public static int getRandom(int[] array) {
    int rnd = (int)(Math.random()*array.length);
    return array[rnd];
}

Math.random()リターンdoubleとの間0.0に(含みます)1.0(排他)

でこれを掛けるとarray.length、あなたが与えられるdouble0.0(両端を含む)とarray.length(排他的)の

キャストするintと、整数と0(両端を含む)とarray.length-1(両端を含む)の間で切り捨てられます


Math.random()は、intではなくdoubleを返します。もしあれば、2つの値0と1しかありません
Akshay R.

1

Java 8を使用しているため、別の解決策はStream APIを使用することです。

new Random().ints(1, 500).limit(500).forEach(p -> System.out.println(list[p]));

1生成されたintの最小値(両端を含む)と500、最大値(両端を含まない)はどこにありますか。limitストリームの長さが500になることを意味します。

 int[] list = new int[] {1,2,3,4,5,6};
 new Random().ints(0, list.length).limit(10).forEach(p -> System.out.println(list[p])); 

ランダムはjava.utilパッケージからのものです。



0

Javaのjava.utilパッケージにはRandomクラスがあります。これを使用すると、次のことができます。

Random rnd = new Random();
int randomNumberFromArray = array[rnd.nextInt(3)];

お役に立てれば!


0
package workouts;

import java.util.Random;

/**
 *
 * @author Muthu
 */
public class RandomGenerator {
    public static void main(String[] args) {
     for(int i=0;i<5;i++){
         rndFunc();
     } 
    }
     public static void rndFunc(){
           int[]a= new int[]{1,2,3};
           Random rnd= new Random();
           System.out.println(a[rnd.nextInt(a.length)]);
       }
}

0

このアプローチを試すこともできます。

public static <E> E[] pickRandom_(int n,E ...item) {
        List<E> copy = Arrays.asList(item);
        Collections.shuffle(copy);
        if (copy.size() > n) {
            return (E[]) copy.subList(0, n).toArray();
        } else {
            return (E[]) copy.toArray();
        }

    }

したがって、O(nlogn)時間の複雑さとリストをシャッフルし、OPが尋ねた問題がO(1)時間の複雑さとO(1)メモリで解決できるとしても、最初の配列の合計3倍のメモリを使用して2回コピーを作成します...?
Jaroslaw Pawlak、

はい、あなたは正しいです。それは、一定の時間と空間の複雑さで行う方がよかったです。
ラビサパリヤ2018年

0
package io.github.baijifeilong.tmp;

import java.util.concurrent.ThreadLocalRandom;
import java.util.stream.Stream;

/**
 * Created by BaiJiFeiLong@gmail.com at 2019/1/3 下午7:34
 */
public class Bar {
    public static void main(String[] args) {
        Stream.generate(() -> null).limit(10).forEach($ -> {
            System.out.println(new String[]{"hello", "world"}[ThreadLocalRandom.current().nextInt(2)]);
        });
    }
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.