Crear números aleatorios sin duplicados

En este caso, el MAX es solo 5, así que pude verificar los duplicados uno por uno, pero ¿cómo podría hacer esto de una manera más simple? Por ejemplo, ¿qué pasa si el MAX tiene un valor de 20? Gracias.

int MAX = 5; for (i = 1 , i <= MAX; i++) { drawNum[1] = (int)(Math.random()*MAX)+1; while (drawNum[2] == drawNum[1]) { drawNum[2] = (int)(Math.random()*MAX)+1; } while ((drawNum[3] == drawNum[1]) || (drawNum[3] == drawNum[2]) ) { drawNum[3] = (int)(Math.random()*MAX)+1; } while ((drawNum[4] == drawNum[1]) || (drawNum[4] == drawNum[2]) || (drawNum[4] == drawNum[3]) ) { drawNum[4] = (int)(Math.random()*MAX)+1; } while ((drawNum[5] == drawNum[1]) || (drawNum[5] == drawNum[2]) || (drawNum[5] == drawNum[3]) || (drawNum[5] == drawNum[4]) ) { drawNum[5] = (int)(Math.random()*MAX)+1; } } 

La forma más simple sería crear una lista de los números posibles (1..20 o lo que sea) y luego mezclarlos con Collections.shuffle . Luego solo toma los elementos que quieras. Esto es genial si su rango es igual al número de elementos que necesita al final (por ejemplo, para barajar una baraja de cartas).

Eso no funciona tan bien si quieres (digamos) 10 elementos aleatorios en el rango 1..10,000 – terminarías haciendo mucho trabajo innecesariamente. En ese momento, probablemente sea mejor mantener un conjunto de valores que haya generado hasta ahora, y solo siga generando números en un bucle hasta que el siguiente no esté presente:

 if (max < numbersNeeded) { throw new IllegalArgumentException("Can't ask for more numbers than are available"); } Random rng = new Random(); // Ideally just create one instance globally // Note: use LinkedHashSet to maintain insertion order Set generated = new LinkedHashSet(); while (generated.size() < numbersNeeded) { Integer next = rng.nextInt(max) + 1; // As we're adding to a set, this will automatically do a containment check generated.add(next); } 

Sin embargo, tenga cuidado con la opción elegida: he usado deliberadamente LinkedHashSet ya que mantiene el orden de inserción, lo cual nos importa aquí.

Otra opción es progresar siempre , reduciendo el rango cada vez y compensando los valores existentes. Entonces, por ejemplo, supongamos que quiere 3 valores en el rango de 0..9. En la primera iteración generaría cualquier número en el rango de 0..9 - digamos que genera un 4.

En la segunda iteración, generaría un número en el rango de 0,8. Si el número generado es menor que 4, lo mantendría como está ... de lo contrario, se agregará uno. Eso te da un rango de resultados de 0..9 sin 4. Supongamos que obtenemos 7 de esa manera.

En la tercera iteración generarías un número en el rango 0..7. Si el número generado es menor que 4, lo mantendría tal como está. Si es 4 o 5, deberías agregar uno. Si es 6 o 7, agregaría dos. De esta forma, el rango de resultados es 0..9 sin 4 o 6.

Así es como lo haría

 import java.util.ArrayList; import java.util.Random; public class Test { public static void main(String[] args) { int size = 20; ArrayList list = new ArrayList(size); for(int i = 1; i <= size; i++) { list.add(i); } Random rand = new Random(); while(list.size() > 0) { int index = rand.nextInt(list.size()); System.out.println("Selected: "+list.remove(index)); } } } 

Como el estimado Sr. Skeet ha señalado:
Si n es la cantidad de números seleccionados aleatoriamente que desea elegir y N es el espacio total de muestra de los números disponibles para la selección:

  1. Si n << N , solo debe almacenar los números que ha elegido y consultar una lista para ver si el número seleccionado está en ella.
  2. Si n ~ = N , probablemente deberías usar mi método, completando una lista que contenga todo el espacio de muestra y luego eliminando los números a medida que los seleccionas.
 //random numbers are 0,1,2,3 ArrayList numbers = new ArrayList(); Random randomGenerator = new Random(); while (numbers.size() < 4) { int random = randomGenerator .nextInt(4); if (!numbers.contains(random)) { numbers.add(random); } } 

Hay otra forma de hacer números ordenados “aleatorios” con LFSR, eche un vistazo a:

http://en.wikipedia.org/wiki/Linear_feedback_shift_register

Con esta técnica puede obtener el número aleatorio ordenado por índice y asegurarse de que los valores no estén duplicados.

Pero estos no son verdaderos números aleatorios porque la generación aleatoria es determinista.

Pero dependiendo de su caso , puede utilizar esta técnica, reduciendo la cantidad de procesamiento en la generación de números aleatorios al usar la mezcla.

Aquí un algoritmo LFSR en Java, (lo llevé a un lugar que no recuerdo):

 public final class LFSR { private static final int M = 15; // hard-coded for 15-bits private static final int[] TAPS = {14, 15}; private final boolean[] bits = new boolean[M + 1]; public LFSR() { this((int)System.currentTimeMillis()); } public LFSR(int seed) { for(int i = 0; i < M; i++) { bits[i] = (((1 << i) & seed) >>> i) == 1; } } /* generate a random int uniformly on the interval [-2^31 + 1, 2^31 - 1] */ public short nextShort() { //printBits(); // calculate the integer value from the registers short next = 0; for(int i = 0; i < M; i++) { next |= (bits[i] ? 1 : 0) << i; } // allow for zero without allowing for -2^31 if (next < 0) next++; // calculate the last register from all the preceding bits[M] = false; for(int i = 0; i < TAPS.length; i++) { bits[M] ^= bits[M - TAPS[i]]; } // shift all the registers for(int i = 0; i < M; i++) { bits[i] = bits[i + 1]; } return next; } /** returns random double uniformly over [0, 1) */ public double nextDouble() { return ((nextShort() / (Integer.MAX_VALUE + 1.0)) + 1.0) / 2.0; } /** returns random boolean */ public boolean nextBoolean() { return nextShort() >= 0; } public void printBits() { System.out.print(bits[M] ? 1 : 0); System.out.print(" -> "); for(int i = M - 1; i >= 0; i--) { System.out.print(bits[i] ? 1 : 0); } System.out.println(); } public static void main(String[] args) { LFSR rng = new LFSR(); Vector vec = new Vector(); for(int i = 0; i <= 32766; i++) { short next = rng.nextShort(); // just testing/asserting to make // sure the number doesn't repeat on a given list if (vec.contains(next)) throw new RuntimeException("Index repeat: " + i); vec.add(next); System.out.println(next); } } } 

La forma más eficiente y básica de tener números aleatorios no repetidos se explica mediante este pseudocódigo. No es necesario tener bucles nesteds o búsquedas hash:

 // get 5 unique random numbers, possible values 0 - 19 // (assume desired number of selections < number of choices) const int POOL_SIZE = 20; const int VAL_COUNT = 5; declare Array mapping[POOL_SIZE]; declare Array results[VAL_COUNT]; declare i int; declare r int; declare max_rand int; // create mapping array for (i=0; i 

Supongamos que la primera iteración genera un número aleatorio 3 para comenzar (de 0 a 19). Esto haría que los resultados [0] = mapeo [3], es decir, el valor 3. Entonces asignaríamos mapeo [3] a 19.

En la siguiente iteración, el número aleatorio fue 5 (de 0 a 18). Esto haría que los resultados [1] = mapeo [5], es decir, el valor 5. Entonces asignaríamos el mapeo [5] a 18.

Ahora suponga que la siguiente iteración eligió 3 nuevamente (de 0 a 17). los resultados [2] se asignarán al valor del mapeo [3], pero ahora, este valor no es 3, sino 19.

Esta misma protección persiste para todos los números, incluso si tiene el mismo número 5 veces seguidas. Por ejemplo, si el generador de números aleatorios le dio 0 cinco veces seguidas, los resultados serían: [0, 19, 18, 17, 16].

Nunca obtendrías el mismo número dos veces.

Generar todos los índices de una secuencia generalmente es una mala idea, ya que puede llevar mucho tiempo, especialmente si la relación de los números a ser elegidos a MAX es baja (la complejidad se ve dominada por O(MAX) ). Esto empeora si la relación de los números a ser elegidos a MAX aproxima a uno, ya que también resulta costoso eliminar los índices elegidos de la secuencia de todos (nos aproximamos a O(MAX^2/2) ). Pero para números pequeños, esto generalmente funciona bien y no es particularmente propenso a errores.

Filtrar los índices generados mediante el uso de una colección también es una mala idea, ya que se dedica un tiempo a insertar los índices en la secuencia, y el progreso no está garantizado ya que se puede dibujar el mismo número aleatorio varias veces (pero para un MAX suficientemente grande improbable). Esto podría estar cerca de la complejidad
O(kn log^2(n)/2) , ignorando los duplicados y asumiendo que la colección usa un árbol para una búsqueda eficiente (pero con un costo constante significativo k de asignar los nodos de árbol y posiblemente tener que reequilibrar ).

Otra opción es generar los valores aleatorios de forma única desde el principio, garantizando el progreso. Eso significa que en la primera ronda, se genera un índice aleatorio en [0, MAX] :

 items i0 i1 i2 i3 i4 i5 i6 (total 7 items) idx 0 ^^ (index 2) 

En la segunda ronda, solo se genera [0, MAX - 1] (ya que un elemento ya estaba seleccionado):

 items i0 i1 i3 i4 i5 i6 (total 6 items) idx 1 ^^ (index 2 out of these 6, but 3 out of the original 7) 

Los valores de los índices luego deben ajustarse: si el segundo índice cae en la segunda mitad de la secuencia (después del primer índice), debe incrementarse para tener en cuenta la brecha. Podemos implementar esto como un bucle, lo que nos permite seleccionar un número arbitrario de elementos únicos.

Para secuencias cortas, este es un algoritmo O(n^2/2) bastante rápido:

 void RandomUniqueSequence(std::vector &rand_num, const size_t n_select_num, const size_t n_item_num) { assert(n_select_num <= n_item_num); rand_num.clear(); // !! // b1: 3187.000 msec (the fastest) // b2: 3734.000 msec for(size_t i = 0; i < n_select_num; ++ i) { int n = n_Rand(n_item_num - i - 1); // get a random number size_t n_where = i; for(size_t j = 0; j < i; ++ j) { if(n + j < rand_num[j]) { n_where = j; break; } } // see where it should be inserted rand_num.insert(rand_num.begin() + n_where, 1, n + n_where); // insert it in the list, maintain a sorted sequence } // tier 1 - use comparison with offset instead of increment } 

Donde n_select_num es su 5 y n_number_num es su MAX . n_Rand(x) devuelve enteros aleatorios en [0, x] (inclusive). Esto se puede hacer un poco más rápido si se seleccionan muchos elementos (p. Ej., No 5 sino 500) mediante el uso de búsqueda binaria para encontrar el punto de inserción. Para hacer eso, debemos asegurarnos de cumplir con los requisitos.

Haremos búsqueda binaria con la comparación n + j < rand_num[j] que es lo mismo que
n < rand_num[j] - j . Necesitamos mostrar que rand_num[j] - j sigue siendo una secuencia ordenada para una secuencia ordenada rand_num[j] . Afortunadamente, esto se muestra fácilmente, ya que la distancia más baja entre dos elementos del rand_num original es uno (los números generados son únicos, por lo que siempre hay una diferencia de al menos 1). Al mismo tiempo, si restamos los índices j de todos los elementos
rand_num[j] , las diferencias en el índice son exactamente 1. Entonces, en el "peor" caso, obtenemos una secuencia constante, pero nunca disminuyendo. La búsqueda binaria puede por lo tanto ser utilizada, produciendo el algoritmo O(n log(n)) :

 struct TNeedle { // in the comparison operator we need to make clear which argument is the needle and which is already in the list; we do that using the type system. int n; TNeedle(int _n) :n(_n) {} }; class CCompareWithOffset { // custom comparison "n < rand_num[j] - j" protected: std::vector::iterator m_p_begin_it; public: CCompareWithOffset(std::vector::iterator p_begin_it) :m_p_begin_it(p_begin_it) {} bool operator ()(const int &r_value, TNeedle n) const { size_t n_index = &r_value - &*m_p_begin_it; // calculate index in the array return r_value < nn + n_index; // or r_value - n_index < nn } bool operator ()(TNeedle n, const int &r_value) const { size_t n_index = &r_value - &*m_p_begin_it; // calculate index in the array return nn + n_index < r_value; // or nn < r_value - n_index } }; 

Y finalmente:

 void RandomUniqueSequence(std::vector &rand_num, const size_t n_select_num, const size_t n_item_num) { assert(n_select_num <= n_item_num); rand_num.clear(); // !! // b1: 3578.000 msec // b2: 1703.000 msec (the fastest) for(size_t i = 0; i < n_select_num; ++ i) { int n = n_Rand(n_item_num - i - 1); // get a random number std::vector::iterator p_where_it = std::upper_bound(rand_num.begin(), rand_num.end(), TNeedle(n), CCompareWithOffset(rand_num.begin())); // see where it should be inserted rand_num.insert(p_where_it, 1, n + p_where_it - rand_num.begin()); // insert it in the list, maintain a sorted sequence } // tier 4 - use binary search } 

Lo he probado en tres puntos de referencia. En primer lugar, se seleccionaron 3 números de 7 elementos, y se acumuló un histogtwig de los elementos elegidos en más de 10,000 carreras:

 4265 4229 4351 4267 4267 4364 4257 

Esto muestra que cada uno de los 7 elementos fue elegido aproximadamente el mismo número de veces, y no hay un sesgo aparente causado por el algoritmo. Todas las secuencias también se verificaron para la corrección (unicidad del contenido).

El segundo punto de referencia implicó elegir 7 números de 5000 artículos. El tiempo de varias versiones del algoritmo se acumuló en más de 10,000,000 ejecuciones. Los resultados se indican en comentarios en el código como b1 . La versión simple del algoritmo es ligeramente más rápida.

El tercer punto de referencia implicó elegir 700 números de 5000 artículos. El tiempo de varias versiones del algoritmo se acumuló nuevamente, esta vez más de 10,000 carreras. Los resultados se indican en comentarios en el código como b2 . La versión de búsqueda binaria del algoritmo es ahora más de dos veces más rápida que la simple.

El segundo método comienza a ser más rápido para elegir más de 75 elementos en mi máquina (tenga en cuenta que la complejidad de cualquiera de los algoritmos no depende del número de elementos, MAX ).

Vale la pena mencionar que los algoritmos anteriores generan los números aleatorios en orden ascendente. Pero sería simple agregar otra matriz a la que se guardarían los números en el orden en que se generaron, y devolverla en su lugar (a un costo adicional insignificante O(n) ). No es necesario mezclar la salida: eso sería mucho más lento.

Tenga en cuenta que las fonts están en C ++, no tengo Java en mi máquina, pero el concepto debe ser claro.

EDITAR :

Por diversión, también he implementado el enfoque que genera una lista con todos los índices
0 .. MAX , los elige al azar y los elimina de la lista para garantizar la exclusividad. Como he elegido MAX (5000) bastante alto, el rendimiento es catastrófico:

 // b1: 519515.000 msec // b2: 20312.000 msec std::vector all_numbers(n_item_num); std::iota(all_numbers.begin(), all_numbers.end(), 0); // generate all the numbers for(size_t i = 0; i < n_number_num; ++ i) { assert(all_numbers.size() == n_item_num - i); int n = n_Rand(n_item_num - i - 1); // get a random number rand_num.push_back(all_numbers[n]); // put it in the output list all_numbers.erase(all_numbers.begin() + n); // erase it from the input } // generate random numbers 

También he implementado el enfoque con un set (una colección de C ++), que en realidad ocupa el segundo lugar en el punto de referencia b2 , siendo solo un 50% más lento que el enfoque con la búsqueda binaria. Eso es comprensible, ya que el set usa un árbol binario, donde el costo de inserción es similar a la búsqueda binaria. La única diferencia es la posibilidad de obtener elementos duplicados, lo que ralentiza el progreso.

 // b1: 20250.000 msec // b2: 2296.000 msec std::set numbers; while(numbers.size() < n_number_num) numbers.insert(n_Rand(n_item_num - 1)); // might have duplicates here // generate unique random numbers rand_num.resize(numbers.size()); std::copy(numbers.begin(), numbers.end(), rand_num.begin()); // copy the numbers from a set to a vector 

El código fuente completo está aquí .

Otro enfoque que le permite especificar cuántos números desea con el size y los valores min y max de los números devueltos

 public static int getRandomInt(int min, int max) { Random random = new Random(); return random.nextInt((max - min) + 1) + min; } public static ArrayList getRandomNonRepeatingIntegers(int size, int min, int max) { ArrayList numbers = new ArrayList(); while (numbers.size() < size) { int random = getRandomInt(min, max); if (!numbers.contains(random)) { numbers.add(random); } } return numbers; } 

Para usarlo, devuelve 7 números entre 0 y 25.

  ArrayList list = getRandomNonRepeatingIntegers(7, 0, 25); for (int i = 0; i < list.size(); i++) { System.out.println("" + list.get(i)); } 

Puede usar una de las clases que implementan la interfaz Set ( API ) y luego cada número que genere, use Set.add () para insertarlo.

Si el valor de retorno es falso, usted sabe que el número ya se ha generado antes.

En lugar de hacer todo esto, cree un objeto LinkedHashSet y números aleatorios mediante la función Math.random() …. si se produce una entrada duplicada, el objeto LinkedHashSet no agregará ese número a su lista … Dado que en esta clase de colección no se permiten valores duplicados … al final se obtiene una lista de números aleatorios que no tienen valores duplicados ….: D

Tu problema parece reducirse para elegir k elementos al azar de una colección de n elementos. La respuesta Collections.shuffle es, por lo tanto, correcta, pero como se señaló ineficiente: es O (n).

Wikipedia: la combinación aleatoria de Fisher-Yates tiene una versión O (k) cuando la matriz ya existe. En su caso, no existe una matriz de elementos y la creación de la matriz de elementos podría ser muy costosa, por ejemplo, si max fueran 10000000 en lugar de 20.

El algoritmo aleatorio implica inicializar una matriz de tamaño n donde cada elemento es igual a su índice, seleccionando k números aleatorios cada número en un rango con el máximo uno menor que el rango anterior, y luego intercambiando elementos hacia el final de la matriz.

Puedes hacer la misma operación en el tiempo O (k) con un hashmap aunque admito que es un poco doloroso. Tenga en cuenta que esto solo vale la pena si k es mucho menor que n. (es decir, k ~ lg (n) más o menos), de lo contrario, debería usar la reproducción aleatoria directamente.

Utilizará su hashmap como una representación eficiente de la matriz de respaldo en el algoritmo de mezcla. Cualquier elemento de la matriz que sea igual a su índice no necesita aparecer en el mapa. Esto le permite representar una matriz de tamaño n en tiempo constante, no hay tiempo dedicado a inicializarla.

  1. Elija k números aleatorios: el primero está en el rango 0 a n-1, el segundo 0 a n-2, el tercero 0 a n-3 y así sucesivamente, a través de nk.

  2. Trate sus números aleatorios como un conjunto de intercambios. El primer índice aleatorio cambia a la posición final. El segundo índice aleatorio cambia a la penúltima posición. Sin embargo, en lugar de trabajar contra una matriz de respaldo, trabaje en contra de su hashmap. Su hashmap almacenará cada elemento que está fuera de posición.


int getValue(i) { if (map.contains(i)) return map[i]; return i; } void setValue(i, val) { if (i == val) map.remove(i); else map[i] = val; } int[] chooseK(int n, int k) { for (int i = 0; i < k; i++) { int randomIndex = nextRandom(0, n - i); //(n - i is exclusive) int desiredIndex = ni-1; int valAtRandom = getValue(randomIndex); int valAtDesired = getValue(desiredIndex); setValue(desiredIndex, valAtRandom); setValue(randomIndex, valAtDesired); } int[] output = new int[k]; for (int i = 0; i < k; i++) { output[i] = (getValue(ni-1)); } return output; }

Hay un algoritmo de lotes de cartas: crea una matriz ordenada de números (el “lote de tarjetas”) y en cada iteración selecciona un número en una posición aleatoria (eliminando el número seleccionado del “lote de tarjetas”, por supuesto).

Aquí hay una solución eficiente para la creación rápida de una matriz aleatoria. Después de la aleatorización, simplemente puede elegir el enésimo elemento e de la matriz, incrementar n devolver e . Esta solución tiene O (1) para obtener un número aleatorio y O (n) para la inicialización, pero como solución de compromiso requiere una buena cantidad de memoria si n es lo suficientemente grande.

Hay una solución más eficiente y menos engorrosa para los enteros que un Collections.shuffle.

El problema es lo mismo que elegir sucesivamente elementos de solo los elementos no recogidos en un conjunto y configurarlos en otro lugar. Esto es exactamente como repartir aleatoriamente cartas o sacar boletos de la rifa ganadora de un sombrero o una papelera.

Este algoritmo funciona para cargar cualquier matriz y lograr un orden aleatorio al final de la carga. También funciona para agregarlo a una colección de listas (o cualquier otra colección indexada) y lograr una secuencia aleatoria en la colección al final de las adiciones.

Se puede hacer con una única matriz, creada una vez, o una colección ordenada numéricamente, como una lista, en su lugar. Para una matriz, el tamaño de la matriz inicial debe ser el tamaño exacto para contener todos los valores previstos. Si no sabe cuántos valores pueden ocurrir de antemano, también funcionará el uso de una colección ordenada numéricamente, como ArrayList o List, donde el tamaño no es inmutable. Funcionará universalmente para una matriz de cualquier tamaño hasta Integer.MAX_VALUE que es un poco más de 2,000,000,000. Los objetos de lista tendrán los mismos límites de índice. Es posible que su máquina se quede sin memoria antes de llegar a una matriz de ese tamaño. Puede ser más eficiente cargar una matriz escrita a los tipos de objeto y convertirla en una colección, después de cargar la matriz. Esto es especialmente cierto si la colección objective no está indexada numéricamente.

Este algoritmo, exactamente como está escrito, creará una distribución muy pareja donde no haya duplicados. Un aspecto que es MUY IMPORTANTE es que tiene que ser posible insertar el siguiente elemento hasta el tamaño actual + 1. Por lo tanto, para el segundo elemento, podría ser posible almacenarlo en la ubicación 0 o en la ubicación 1 Para el 20º artículo, podría ser posible almacenarlo en cualquier ubicación, del 0 al 19. Es posible que el primer artículo permanezca en la ubicación 0, ya que termina en cualquier otra ubicación. Es igual de posible para el próximo artículo nuevo ir a cualquier lugar, incluida la próxima ubicación nueva.

La aleatoriedad de la secuencia será tan aleatoria como la aleatoriedad del generador de números aleatorios.

Este algoritmo también se puede usar para cargar tipos de referencia en ubicaciones aleatorias en una matriz. Como esto funciona con una matriz, también puede funcionar con colecciones. Eso significa que no tiene que crear la colección y luego barajarla u ordenarla en cualquier orden que los objetos se inserten. La colección solo necesita tener la capacidad de insertar un elemento en cualquier lugar de la colección o anexarlo.

 // RandomSequence.java import java.util.Random; public class RandomSequence { public static void main(String[] args) { // create an array of the size and type for which // you want a random sequence int[] randomSequence = new int[20]; Random randomNumbers = new Random(); for (int i = 0; i < randomSequence.length; i++ ) { if (i == 0) { // seed first entry in array with item 0 randomSequence[i] = 0; } else { // for all other items... // choose a random pointer to the segment of the // array already containing items int pointer = randomNumbers.nextInt(i + 1); randomSequence[i] = randomSequence[pointer]; randomSequence[pointer] = i; // note that if pointer & i are equal // the new value will just go into location i and possibly stay there // this is VERY IMPORTANT to ensure the sequence is really random // and not biased } // end if...else } // end for for (int number: randomSequence) { System.out.printf("%2d ", number); } // end for } // end main } // end class RandomSequence 

Realmente todo depende de exactamente para qué necesitas la generación aleatoria, pero esta es mi opinión.

Primero, cree un método independiente para generar el número aleatorio. Asegúrese de permitir los límites.

 public static int newRandom(int limit){ return generatedRandom.nextInt(limit); } 

Luego, querrás crear una estructura de decisión muy simple que compare valores. Esto se puede hacer de una de dos maneras. Si tiene una cantidad muy limitada de números para verificar, bastará con una simple statement IF:

 public static int testDuplicates(int int1, int int2, int int3, int int4, int int5){ boolean loopFlag = true; while(loopFlag == true){ if(int1 == int2 || int1 == int3 || int1 == int4 || int1 == int5 || int1 == 0){ int1 = newRandom(75); loopFlag = true; } else{ loopFlag = false; }} return int1; } 

Lo anterior compara int1 a int2 a int5, y también se asegura de que no haya ceros en los randoms.

Con estos dos métodos en su lugar, podemos hacer lo siguiente:

  num1 = newRandom(limit1); num2 = newRandom(limit1); num3 = newRandom(limit1); num4 = newRandom(limit1); num5 = newRandom(limit1); 

Seguido por:

  num1 = testDuplicates(num1, num2, num3, num4, num5); num2 = testDuplicates(num2, num1, num3, num4, num5); num3 = testDuplicates(num3, num1, num2, num4, num5); num4 = testDuplicates(num4, num1, num2, num3, num5); num5 = testDuplicates(num5, num1, num2, num3, num5); 

Si tiene una lista más larga para verificar, entonces un método más complejo arrojará mejores resultados tanto en la claridad del código como en los recursos de procesamiento.

Espero que esto ayude. Este sitio me ha ayudado tanto que me sentí obligado por lo menos a TRY a ayudar también.