Generando números aleatorios únicos en C

Intenté generar 10 números aleatorios únicos en C. Tengo un número de matriz numout[] para 10 números pero esto llega a “falla de segmentación” después de algún tiempo.

El código de Tho es:

 int i,j,numout[10],randnum; void main() { srand(time(NULL)); for(i=0;i<10;i++) { numout[i]=generate(); printf("%d",numout[i]); fflush(stdout); sleep(1); printf("\b"); } } int generate() { randnum=1+(int)(rand()*mul_val/(RAND_MAX+1.0)); for(j=0;j<i;j++) { if(randnum==0 || randnum==numout[j]) { randnum=generate(); } } return(randnum); } 

Tira ese código, en serio. Necesita un algoritmo de orden aleatorio, no un fragmento de código que verifique los valores antiguos en busca de duplicados. Hacerlo a su manera terminará demorándose cada vez más a medida que se agote su grupo. La ventaja de un algoritmo de barajado es que no se degrada a medida que el grupo se hace más pequeño.

Aquí hay un fragmento de código que utilicé para responder una pregunta diferente. Mantiene una lista de números y, cuando le devuelve uno aleatorio, lo elimina de la lista y disminuye la cuenta para la siguiente selección aleatoria.

 #include  #include  #define ERR_NO_NUM -1 #define ERR_NO_MEM -2 int myRandom (int size) { int i, n; static int numNums = 0; static int *numArr = NULL; // Initialize with a specific size. if (size >= 0) { if (numArr != NULL) free (numArr); if ((numArr = malloc (sizeof(int) * size)) == NULL) return ERR_NO_MEM; for (i = 0; i < size; i++) numArr[i] = i; numNums = size; } // Error if no numbers left in pool. if (numNums == 0) return ERR_NO_NUM; // Get random number from pool and remove it (rnd in this // case returns a number between 0 and numNums-1 inclusive). n = rand() % numNums; i = numArr[n]; numArr[n] = numArr[numNums-1]; numNums--; if (numNums == 0) { free (numArr); numArr = 0; } return i; } int main (void) { int i; srand (time (NULL)); i = myRandom (20); while (i >= 0) { printf ("Number = %3d\n", i); i = myRandom (-1); } printf ("Final = %3d\n", i); return 0; } 

Una salida de muestra lo muestra en acción:

 Number = 19 Number = 10 Number = 2 Number = 15 Number = 0 Number = 6 Number = 1 Number = 3 Number = 17 Number = 14 Number = 12 Number = 18 Number = 4 Number = 9 Number = 7 Number = 8 Number = 16 Number = 5 Number = 11 Number = 13 Final = -1 

Llámelo con un tamaño de grupo no negativo y configura una nueva secuencia y devuelve el primer valor aleatorio. A continuación, puede llamarlo con -1 y obtendrá el siguiente número aleatorio y único de la agrupación. Cuando la piscina se agota, devolverá -1.

La otra respuesta que contenía este código tiene una versión que puede mantener varias agrupaciones también si desea poder utilizar esta función en el código de subprocesos.

Obtendrá un error de segmentación cuando se quede sin espacio de stack. Su código es recursivo (es decir, generate() generate() ). Así que cuando te quedes sin números aleatorios no utilizados, se llamará a sí mismo para siempre.

Sin embargo, no recomendaré una solución para su código, ya que realmente necesita escribirlo nuevamente desde cero. Sigue el ejemplo de paxdiablo.

Si necesita un gran conjunto de números aleatorios únicos, debe considerar el uso del enfoque LFSR. LFSR genera números aleatorios únicos que no se repiten a menos que se agote toda la agrupación, por lo que un LFSR de 32 bits generará 2 ^ 32 – 1 números aleatorios únicos – No genera 0. La encoding es sencilla, búsquelo google.

 The program below stores n unique random numbers ie, from [1 to n] in an array. #include #include void main() { int i, j, Array[100]; cout<<"Enter value of n : "; //upper limit cin>>n; randomize(); int rnd; Array[1]=rand()%n+1; for(i=2;i<=n;i++) { rnd=rand()%n+1; for(j=1;j=i) Array[i]=rnd; } //for printing from random numbers from 1 to n for(i=1;i<=n;i++) cout<