Como escolher aleatoriamente um elemento de uma matriz

94

Estou procurando uma solução para escolher o número aleatoriamente de uma matriz de inteiros.

Por exemplo, eu tenho uma matriz new int[]{1,2,3}, como posso escolher um número aleatoriamente?

BreakHead
fonte
Consulte isto
Mithun Sasidharan

Respostas:

182
public static int getRandom(int[] array) {
    int rnd = new Random().nextInt(array.length);
    return array[rnd];
}
Chris Dennett
fonte
2
sim, mas você deve dizer que generatoré uma instância dejava.util.Random
stivlo
25
Eu não criaria Random()cada vez que você executasse a função: o gerador aleatório deveria ter histórico. Se não, é extremamente previsível. Não é um problema neste caso - mas deve ser mencionado que array[(int)(System.currentTimeMillis() % array.length)]é tão bom quanto a solução proposta.
alf
4
@alf, isso está longe de ser tão bom quanto a solução proposta. new Random()tenta criar uma instância que possui uma semente diferente de qualquer outra criada anteriormente Random. Sua abordagem seria horrível apenas invocando a função duas vezes em um curto espaço de tempo.
aioobe
1
@alf alguns sistemas não têm um relógio preciso milissegundo, o que pode impedir algumas opções segcd(array.length,clockAccuracy)!=1
loucura por catraca
3
Acabei de notar uma notificação de que votei abaixo do valor desta resposta - devo ter clicado acidentalmente; infelizmente, a interface não me deixa desfazer (diz que não posso mudar meu voto a menos que a resposta seja editada ...). Então, desculpas a Chris Dennett.
Peter Hanley
13

Você pode usar o gerador Random para gerar um índice aleatório e retornar o elemento nesse índice:

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

Se você for obter um elemento aleatório várias vezes, certifique-se de que o gerador de números aleatórios seja inicializado apenas uma vez.

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)];
    }
}

Se estiver escolhendo elementos de array aleatórios que precisam ser imprevisíveis, você deve usar java.security.SecureRandom em vez de Random. Isso garante que, se alguém souber as últimas escolhas, não terá vantagem em adivinhar a próxima.

Se você deseja escolher um número aleatório de uma matriz Object usando genéricos, pode definir um método para fazer isso (Fonte Avinash R no elemento Random da matriz de string ):

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)]; 
    }
}
Stephen Ostermiller
fonte
3

use java.util.Randompara gerar um número aleatório entre 0 e o comprimento da matriz: random_numbere, em seguida, use o número aleatório para obter o inteiro:array[random_number]

James.Xu
fonte
3

Use a classe Random :

int getRandomNumber(int[] arr)
{
  return arr[(new Random()).nextInt(arr.length)];
}
AlQafir
fonte
2

Você também pode usar

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

Math.random()retorna um doubleentre 0.0(inclusivo) a 1.0(exclusivo)

Multiplicar isso por array.lengthdá a você um valor doubleentre 0.0(inclusivo) e array.length(exclusivo)

Cast para intarredondará para baixo, fornecendo a você um número inteiro entre 0(inclusivo) e array.length-1(inclusivo)

aberração da catraca
fonte
Math.random () retorna um double e não um int. Se tivesse, teria havido apenas dois valores possíveis 0 e 1.
Akshay R.
1

Como você tem o java 8, outra solução é usar a API Stream.

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

Onde 1é o menor int gerado (inclusivo) e 500é o maior (exclusivo). limitsignifica que seu stream terá uma duração de 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])); 

Random é do java.utilpacote.

Johnny Willer
fonte
0

Java tem uma classe Random no pacote java.util. Usando-o, você pode fazer o seguinte:

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

Espero que isto ajude!

decden
fonte
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)]);
       }
}

fonte
0

Você também pode tentar essa abordagem.

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();
        }

    }
Ravi Sapariya
fonte
Então você embaralha uma lista com O(nlogn)complexidade de tempo, faz a cópia dela duas vezes usando o total de 3 vezes mais memória do que o array inicial, embora o problema que o OP perguntou possa ser resolvido com O(1)complexidade de tempo e O(1)memória ...?
Jaroslaw Pawlak
sim, você tem razão, era melhor fazer com constante tempo e complexidade espacial.
Ravi Sapariya
0
package io.github.baijifeilong.tmp;

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

/**
 * Created by [email protected] 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)]);
        });
    }
}
BaiJiFeiLong
fonte