Estou tentando obter números aleatórios entre 0 e 100. Mas quero que sejam únicos, não repetidos em uma sequência. Por exemplo, se eu tenho 5 números, eles devem ser 82,12,53,64,32 e não 82,12,53,12,32 Eu usei isso, mas gera os mesmos números em uma sequência.
Random rand = new Random();
selected = rand.nextInt(100);
1..100
(existem algoritmos famosos para isso), mas pare depois de determinar os primeirosn
elementos.Respostas:
Aqui está uma implementação simples. Isso imprimirá 3 números aleatórios exclusivos no intervalo de 1 a 10.
import java.util.ArrayList; import java.util.Collections; public class UniqueRandomNumbers { public static void main(String[] args) { ArrayList<Integer> list = new ArrayList<Integer>(); for (int i=1; i<11; i++) { list.add(new Integer(i)); } Collections.shuffle(list); for (int i=0; i<3; i++) { System.out.println(list.get(i)); } } }
A primeira parte da correção com a abordagem original, como Mark Byers apontou em uma resposta agora excluída, é usar apenas uma única
Random
instância.É isso que está fazendo com que os números sejam idênticos. Uma
Random
instância é propagada pela hora atual em milissegundos. Para um determinado valor de semente, a instância 'aleatória' retornará exatamente a mesma sequência de números pseudo-aleatórios .O primeiro loop for pode simplesmente ser alterado para:
for (int i = 1; i < 11; i++) { list.add(i); }
fonte
Com o Java 8+, você pode usar o
ints
método deRandom
para obter umIntStream
valor aleatóriodistinct
e entãolimit
reduzir o fluxo a um número de valores aleatórios exclusivos.ThreadLocalRandom.current().ints(0, 100).distinct().limit(5).forEach(System.out::println);
Random
também possui métodos que criamLongStream
s eDoubleStream
s se você precisar deles.Se você quiser todos (ou uma grande quantidade) dos números em um intervalo em uma ordem aleatória, pode ser mais eficiente adicionar todos os números a uma lista, embaralhá-la e pegar o primeiro n porque o exemplo acima está implementado atualmente gerando números aleatórios no intervalo solicitado e passando-os por um conjunto (semelhante à resposta de Rob Kielty ), o que pode exigir a geração de muito mais do que a quantidade passada para o limite, pois a probabilidade de gerar um novo número exclusivo diminui com cada um deles encontrado. Aqui está um exemplo da outra maneira:
List<Integer> range = IntStream.range(0, 100).boxed() .collect(Collectors.toCollection(ArrayList::new)); Collections.shuffle(range); range.subList(0, 99).forEach(System.out::println);
fonte
Arrays#setAll()
é um pouco mais rápido do que um fluxo. Portanto: `Índices inteiros [] = novo inteiro [n]; Arrays.setAll (índices, i -> i); Collections.shuffle (Arrays.asList (índices)); return Arrays.stream (índices) .mapToInt (Integer :: intValue) .toArray (); `long
onde você desloca e mascara para acessar bits individuais.)fonte
pick()
é um exemplo.HashSet
, onde armazena os números já gerados e usacontains
para testar se já gerou esse número. AHashSet
provavelmente será um pouco mais lento do que uma matriz booleana, mas ocupam menos memória.Use
Collections.shuffle()
em todos os 100 números e selecione os cinco primeiros, conforme mostrado aqui .fonte
Acho que vale a pena mencionar esse método.
private static final Random RANDOM = new Random(); /** * Pick n numbers between 0 (inclusive) and k (inclusive) * While there are very deterministic ways to do this, * for large k and small n, this could be easier than creating * an large array and sorting, i.e. k = 10,000 */ public Set<Integer> pickRandom(int n, int k) { final Set<Integer> picked = new HashSet<>(); while (picked.size() < n) { picked.add(RANDOM.nextInt(k + 1)); } return picked; }
fonte
Refleti a resposta de Anand para fazer uso não apenas das propriedades únicas de um conjunto, mas também usar o booleano falso retornado por
set.add()
quando uma adição ao conjunto falha.import java.util.HashSet; import java.util.Random; import java.util.Set; public class randomUniqueNumberGenerator { public static final int SET_SIZE_REQUIRED = 10; public static final int NUMBER_RANGE = 100; public static void main(String[] args) { Random random = new Random(); Set set = new HashSet<Integer>(SET_SIZE_REQUIRED); while(set.size()< SET_SIZE_REQUIRED) { while (set.add(random.nextInt(NUMBER_RANGE)) != true) ; } assert set.size() == SET_SIZE_REQUIRED; System.out.println(set); } }
fonte
SET_SIZE_REQUIRED
for grande o suficiente (digamos, mais do queNUMBER_RANGE / 2
então, você obteve um tempo de execução esperado muito maior.Eu fiz isso assim.
Random random = new Random(); ArrayList<Integer> arrayList = new ArrayList<Integer>(); while (arrayList.size() < 6) { // how many numbers u need - it will 6 int a = random.nextInt(49)+1; // this will give numbers between 1 and 50. if (!arrayList.contains(a)) { arrayList.add(a); } }
fonte
Isso funcionará para gerar números aleatórios únicos ................
import java.util.HashSet; import java.util.Random; public class RandomExample { public static void main(String[] args) { Random rand = new Random(); int e; int i; int g = 10; HashSet<Integer> randomNumbers = new HashSet<Integer>(); for (i = 0; i < g; i++) { e = rand.nextInt(20); randomNumbers.add(e); if (randomNumbers.size() <= 10) { if (randomNumbers.size() == 10) { g = 10; } g++; randomNumbers.add(e); } } System.out.println("Ten Unique random numbers from 1 to 20 are : " + randomNumbers); } }
fonte
Uma maneira inteligente de fazer isso é usar expoentes de um elemento primitivo no módulo.
Por exemplo, 2 é uma raiz mod 101 primitiva, o que significa que os poderes de 2 mod 101 fornecem uma sequência não repetitiva que vê todos os números de 1 a 100, inclusive:
2^0 mod 101 = 1 2^1 mod 101 = 2 2^2 mod 101 = 4 ... 2^50 mod 101 = 100 2^51 mod 101 = 99 2^52 mod 101 = 97 ... 2^100 mod 101 = 1
No código Java, você escreveria:
void randInts() { int num=1; for (int ii=0; ii<101; ii++) { System.out.println(num); num= (num*2) % 101; } }
Encontrar uma raiz primitiva para um módulo específico pode ser complicado, mas a função "primroot" do Maple fará isso para você.
fonte
Eu vim aqui de outra pergunta, que é uma duplicata desta pergunta ( Gerando número aleatório único em java )
Armazene de 1 a 100 números em uma matriz.
Gere um número aleatório entre 1 a 100 como posição e retorna a matriz [posição 1] para obter o valor
Depois de usar um número na matriz, marque o valor como -1 (não há necessidade de manter outra matriz para verificar se este número já está sendo usado)
Se o valor na matriz for -1, obtenha o número aleatório novamente para buscar um novo local na matriz.
fonte
Eu tenho uma solução fácil para este problema, com isso podemos facilmente gerar n número de números aleatórios únicos, é lógico que qualquer um pode usá-lo em qualquer linguagem.
for(int i=0;i<4;i++) { rn[i]= GenerateRandomNumber(); for (int j=0;j<i;j++) { if (rn[i] == rn[j]) { i--; } } }
fonte
break;
apósi—;
Embora seja um tópico antigo, adicionar outra opção pode não prejudicar. (As funções lambda do JDK 1.8 parecem tornar isso mais fácil);
O problema pode ser dividido nas seguintes etapas;
Aqui está a função com alguma descrição:
/** * Provided an unsequenced / sequenced list of integers, the function returns unique random IDs as defined by the parameter * @param numberToGenerate * @param idList * @return List of unique random integer values from the provided list */ private List<Integer> getUniqueRandomInts(List<Integer> idList, Integer numberToGenerate) { List<Integer> generatedUniqueIds = new ArrayList<>(); Integer minId = idList.stream().mapToInt (v->v).min().orElseThrow(NoSuchElementException::new); Integer maxId = idList.stream().mapToInt (v->v).max().orElseThrow(NoSuchElementException::new); ThreadLocalRandom.current().ints(minId,maxId) .filter(e->idList.contains(e)) .distinct() .limit(numberToGenerate) .forEach(generatedUniqueIds:: add); return generatedUniqueIds; }
Assim, para obter 11 números aleatórios exclusivos para o objeto de lista 'allIntegers', chamaremos a função como;
List<Integer> ids = getUniqueRandomInts(allIntegers,11);
A função declara novo arrayList 'generatedUniqueIds' e preenche com cada inteiro aleatório exclusivo até o número necessário antes de retornar.
A classe PS ThreadLocalRandom evita valor de semente comum no caso de threads simultâneos.
fonte
tente isso
public class RandomValueGenerator { /** * */ private volatile List<Double> previousGenValues = new ArrayList<Double>(); public void init() { previousGenValues.add(Double.valueOf(0)); } public String getNextValue() { Random random = new Random(); double nextValue=0; while(previousGenValues.contains(Double.valueOf(nextValue))) { nextValue = random.nextDouble(); } previousGenValues.add(Double.valueOf(nextValue)); return String.valueOf(nextValue); } }
fonte
Isso não é significativamente diferente de outras respostas, mas eu queria a matriz de inteiros no final:
Integer[] indices = new Integer[n]; Arrays.setAll(indices, i -> i); Collections.shuffle(Arrays.asList(indices)); return Arrays.stream(indices).mapToInt(Integer::intValue).toArray();
fonte
você pode usar a matriz booleana para preencher o verdadeiro se o valor for tomado, então o conjunto navegar pela matriz booleana para obter o valor conforme dado abaixo
package study; import java.util.ArrayList; import java.util.Arrays; import java.util.List; /* Created By Sachin Rane on Jul 18, 2018 */ public class UniqueRandomNumber { static Boolean[] boolArray; public static void main(String s[]){ List<Integer> integers = new ArrayList<>(); for (int i = 0; i < 10; i++) { integers.add(i); } //get unique random numbers boolArray = new Boolean[integers.size()+1]; Arrays.fill(boolArray, false); for (int i = 0; i < 10; i++) { System.out.print(getUniqueRandomNumber(integers) + " "); } } private static int getUniqueRandomNumber(List<Integer> integers) { int randNum =(int) (Math.random()*integers.size()); if(boolArray[randNum]){ while(boolArray[randNum]){ randNum++; if(randNum>boolArray.length){ randNum=0; } } boolArray[randNum]=true; return randNum; }else { boolArray[randNum]=true; return randNum; } } }
fonte
Escolha n números aleatórios únicos de 0 a m-1.
int[] uniqueRand(int n, int m){ Random rand = new Random(); int[] r = new int[n]; int[] result = new int[n]; for(int i = 0; i < n; i++){ r[i] = rand.nextInt(m-i); result[i] = r[i]; for(int j = i-1; j >= 0; j--){ if(result[i] >= r[j]) result[i]++; } } return result; }
Imagine uma lista contendo números de 0 a m-1. Para escolher o primeiro número, basta usar
rand.nextInt(m)
. Em seguida, remova o número da lista. Agora, restam m-1 números, então ligamosrand.nextInt(m-1)
. O número que obtemos representa a posição na lista. Se for menor que o primeiro número, então é o segundo número, já que a parte da lista anterior ao primeiro número não foi alterada pela remoção do primeiro número. Se a posição for maior ou igual ao primeiro número, o segundo número é posição + 1. Faça alguma derivação adicional, você pode obter este algoritmo.Explicação
Este algoritmo tem complexidade O (n ^ 2). Portanto, é bom para gerar pequenas quantidades de números exclusivos a partir de um grande conjunto. Enquanto o algoritmo baseado em shuffle precisa de pelo menos O (m) para fazer o shuffle.
Além disso, o algoritmo baseado em shuffle precisa de memória para armazenar todos os resultados possíveis para fazer o shuffle, esse algoritmo não precisa.
fonte
Você pode usar a classe Coleções.
Uma classe de utilitário chamada Coleções oferece diferentes ações que podem ser executadas em uma coleção como um ArrayList (por exemplo, pesquisar os elementos, encontrar o elemento máximo ou mínimo, inverter a ordem dos elementos e assim por diante). Uma das ações que ele pode realizar é embaralhar os elementos. O shuffle moverá aleatoriamente cada elemento para uma posição diferente na lista. Ele faz isso usando um objeto Random. Isso significa que é aleatoriedade determinística, mas funcionará na maioria das situações.
Para embaralhar a ArrayList, adicione a importação de Coleções ao início do programa e use o método estático Shuffle. Leva o ArrayList para ser embaralhado como um parâmetro:
import java.util.Collections; import java.util.ArrayList; public class Lottery { public static void main(String[] args) { //define ArrayList to hold Integer objects ArrayList numbers = new ArrayList(); for(int i = 0; i < 100; i++) { numbers.add(i+1); } Collections.shuffle(numbers); System.out.println(numbers); } }
fonte
Você pode gerar n número aleatório único entre 0 e n-1 em java
public static void RandomGenerate(int n) { Set<Integer> st=new HashSet<Integer>(); Random r=new Random(); while(st.size()<n) { st.add(r.nextInt(n)); }
}
fonte
Este é o método mais simples para gerar valores aleatórios exclusivos em um intervalo ou a partir de uma matriz .
Neste exemplo, estarei usando uma matriz predefinida, mas você pode adaptar esse método para gerar números aleatórios também. Primeiro, criaremos um array de amostra para recuperar nossos dados.
ArrayList<Integer> sampleList = new ArrayList<>(); sampleList.add(1); sampleList.add(2); sampleList.add(3); sampleList.add(4); sampleList.add(5); sampleList.add(6); sampleList.add(7); sampleList.add(8);
Agora, a partir do
sampleList
, iremos produzir cinco números aleatórios que são únicos.int n; randomList = new ArrayList<>(); for(int i=0;i<5;i++){ Random random = new Random(); n=random.nextInt(8); //Generate a random index between 0-7 if(!randomList.contains(sampleList.get(n))) randomList.add(sampleList.get(n)); else i--; //reiterating the step }
Isso é conceitualmente muito simples. Se o valor aleatório gerado já existir, reiteraremos a etapa. Isso continuará até que todos os valores gerados sejam exclusivos.
Se você achou esta resposta útil, você pode votar nela, pois é muito simples no conceito em comparação com as outras respostas .
fonte
Verifique isto
public class RandomNumbers { public static void main(String[] args) { // TODO Auto-generated method stub int n = 5; int A[] = uniqueRandomArray(n); for(int i = 0; i<n; i++){ System.out.println(A[i]); } } public static int[] uniqueRandomArray(int n){ int [] A = new int[n]; for(int i = 0; i< A.length; ){ if(i == A.length){ break; } int b = (int)(Math.random() *n) + 1; if(f(A,b) == false){ A[i++] = b; } } return A; } public static boolean f(int[] A, int n){ for(int i=0; i<A.length; i++){ if(A[i] == n){ return true; } } return false; } }
fonte
Abaixo está uma forma que usei para gerar sempre um número único. A função aleatória gera um número e o armazena em um arquivo de texto e, na próxima vez que o verifica no arquivo, compara e gera um novo número exclusivo, portanto, desta forma, há sempre um novo número exclusivo.
public int GenerateRandomNo() { int _min = 0000; int _max = 9999; Random _rdm = new Random(); return _rdm.Next(_min, _max); } public int rand_num() { randnum = GenerateRandomNo(); string createText = randnum.ToString() + Environment.NewLine; string file_path = System.IO.Path.GetDirectoryName(System.Windows.Forms.Application.ExecutablePath) + @"\Invoices\numbers.txt"; File.AppendAllText(file_path, createText); int number = File.ReadLines(file_path).Count(); //count number of lines in file System.IO.StreamReader file = new System.IO.StreamReader(file_path); do { randnum = GenerateRandomNo(); } while ((file.ReadLine()) == randnum.ToString()); file.Close(); return randnum; }
fonte