[Aporte] Numeros Enteros NO repetidos y pseudo-aleatorios (en desorden)

Iniciado por AlbertoBSD, 11 Junio 2016, 18:39 PM

0 Miembros y 1 Visitante están viendo este tema.

AlbertoBSD

Muy buen dia les dejo un funcion que devuelve una arreglo de numeros enteros no repetidos y pseudo-aleatorios.


int *aleatorios_no_repetidos(int max) {
char *no_repetidos = NULL;
int *desorden = NULL;
int r = 0;
register int i = 0;
srand(time(NULL));
while(no_repetidos == NULL){
no_repetidos = calloc(max,sizeof(char));
}
while(desorden == NULL){
desorden = calloc(max,sizeof(int));
}
do {
r = rand() % max;
if(no_repetidos[r] == 0) {
desorden[i] = r;
no_repetidos[r] = 1;
i++;
}
}while(i < max);
free(no_repetidos);
return desorden;
}


Funcion explicada paso a paso:

int *aleatorios_no_repetidos(int max) {
char *no_repetidos = NULL; //Variable auxiliar para determinar si un numero ya fue agregado o no
int *desorden = NULL; //Contenedor con los numeros en desorden y no repetidos
int r = 0; //variable temporal para el numero pseudo-aleatorio
register int i = 0; //contador de numeros en el arreglo desorden
srand(time(NULL)); //inicializamos nuestra funcion random, en otros sistemas se puede utlizar algun otro generador de numeros aleatorios ya que esta implementacion es muy pobre
//Los siguientes ciclos son usados para asignar espacio a no_repetidos, y  desorden respectivamennte se puede omitir el ciclo ya que rara vez calloc devuelve NULL, pero siempre es bueno validar que no exista error en el retorno de calloc
while(no_repetidos == NULL){
no_repetidos = calloc(max,sizeof(char));
}
while(desorden == NULL){
desorden = calloc(max,sizeof(int));
}

//El siguiente ciclo do-while es usado para rellenar los numeros mientras i se menor que el numero maximo
do {
r = rand() % max; //Aqui tenemos nuestro numero aleatorio de 0 a max - 1
if(no_repetidos[r] == 0) { //validamos que r no exista en el arreglo de no_repetidos
desorden[i] = r; //Asignamos r al arreglo de desorden
no_repetidos[r] = 1; //agregamos 1 al arreglo de no_repetidos para que el numero r actual no vuelva ser agregado
i++; //incrementamos i solo dentro del if para solo contabilizar los numeros que agregemos
}
}while(i < max);
free(no_repetidos); //Liberamos el arrgelo auxiliar de no repetidos ya que no lo necesitamos mas
return desorden; //regresamos la apuntador a desorden
}



Para usar esta funcion tenemos el siguiente ejemplo:

#include<stdio.h>
#include<time.h>
#include<stdlib.h>
#include<string.h>

int *aleatorios_no_repetidos(int max);


int main() {
int maximo = 10;
int *numeros = aleatorios_no_repetidos(maximo); // Solo numeros del 0 al 9  en desorden Los cuales son 10 en total
int i = 0;
printf("Numeros aleatorios no repetidos:\n");
while(i < maximo) {
printf("%i\t",numeros[i]);
i++;
}
printf("\n");
free(numeros);
return 0;
}



Salidas de ejemplo:

Numeros aleatorios no repetidos:
9 6 7 5 3 2 8 0 4 1
Numeros aleatorios no repetidos:
6 8 5 9 7 3 0 1 4 2
Numeros aleatorios no repetidos:
3 7 8 6 2 5 1 9 0 4
Numeros aleatorios no repetidos:
3 7 8 6 2 5 1 9 0 4
Numeros aleatorios no repetidos:
3 7 8 6 2 5 1 9 0 4
Numeros aleatorios no repetidos:
0 6 4 2 1 9 3 5 8 7
Numeros aleatorios no repetidos:
0 6 4 2 1 9 3 5 8 7
Numeros aleatorios no repetidos:
0 6 4 2 1 9 3 5 8 7
Numeros aleatorios no repetidos:
7 5 0 6 1 9 8 2 3 4
Numeros aleatorios no repetidos:
7 5 0 6 1 9 8 2 3 4


Cada 2 lineas es una salida de 10 numeros del 0 al 9 no repetidos y en desorden...

Noten que hay veces que se repite por la pobre implementación de rand() con time(), recomiendo si pueden implementar otra forma de aleatorios estaría mucho mejor el programa.

Proximamente agregare el video explicando el código mencionado.

Saludos

Donaciones
1Coffee1jV4gB5gaXfHgSHDz9xx9QSECVW