Problema C

Cyph3r

Hola me gustaria hacer un listado de numeros por ejemplo del 1 al 12 de forma que queden puestos aleatoriamente y sin repetir.

En teoria la estrucutura seria con el srand pero no se me ocurre la forma de hacer que no se repitan dado que si lo tengo que guardar en una lista y hacer un recorrido es muy engorroso.

Se os ocurre alguna forma ?

Gracias.

AvariciA

creas una funcion q genere el numero aleatorio
Segun se genera lo mandas a una funcion q compruebe q no q el numero no este en el vector.
Si el numero no esta en el vector lo guardas y si no, pues q genere otro.

Te pego el codigo si estas muy apurado.

Un saludo ;)

ArcheR

Te pegaría el código, porque sé como es, pero ya no me acuerdo bien de la sintaxis de C (es sencilla, lo sé, pero no tengo muy buena memoria óò), así que AvariciA, le harías un favor, seguro :P

Cyph3r

Ok si eso ya lo se hacer lo unico que pregunte si existia otra forma y encontre una formula matematica pero era demasiado complejo y prefiero mediante una busqueda sequencial.

Gracias.

AvariciA

srand((unsigned) time(&t));
num=(rand()%11)+1;

Asi solo salen numeros del 1-12 si eso es a lo q llamas formula matemática.
A q te refieres con busqueda secuencial?

au!

aLeX

Generate la lista de números de manera ordenada y copialos a otra lista, o en la misma lista, en posiciones aleatorias. Así la desordenas fácilmente.

Es menos costoso que tener que recorrer la lista al generar un número para saber si está o no.

Cyph3r

#4 Eso no es lo que quiero dado que me dara numero repetidos.

#5 Pero si copio los numeros ordenados en otra lista y luego los desordeno tb tendre que recorrerla de forma que no salgan repetidos.

AvariciA

claro, q te salen repetidos, pero cada vez q se genera uno compruebas q no este en la lista, si esta pides otro si no lo copias en al siguiente posición.

Me explico?

#6 No recorres toda la lista, tan solo el numero de posiciones ocupadas por numeros válidos. Es una lista de 6 posiciones en el peor de los casos estamos hablando de 5 comparaciones. Si se genera el algoritmo como he explicado con cambiar el número de rango podra ampliar el radio aleatorio, si defines un TAM max del vector podras cambiarlo para generar listas aleatorias mas extensas. (Claro esta cambiando tb el rango aleatorio, sino el max de tener 12 numeros sin repetición es 12)

S

#7 Inicializa un vector a 0. Cuando te sale un número, y en esa posición del vector hay un 0, pones a 1 esa posición del vector. Si hay un 1, generas otro número. Luego puedes usar una variable para llevar la cuenta de cuántos has generado.

Cyph3r

#9 ein?

S

Creo ser bastante claro...

AvariciA

La solución de #9 me parece mas original.

cabron

Si los números van del 0 al 20, el vector tiene 20 elementos. El elemento 0 representa el número 0, el elemento 1 el número 1, etc...

Si te sale el número 5, comprueba que tiene el elemento 5 del vector. Si el elemento 5 tiene un 0, significa que el número 5 aún no ha salido, si tiene un 1, significa que ya ha salido y está repetido, así que tienes que generar otro.

Anda que te costaba mucho explicárselo... xD

LOc0

Ls solución de #9, a la par de original es la más eficiente, la más breve y la "más mejor" xD...

Salu2 ;)

PD:
#include <stdio.h>
#include <time.h>

int main()
{

int vector[12], contador, aleatorio;

contador=0;

while(contador<12)
{
	vector[contador]=0;
                     contador++;
         }

    
    srand(time(NULL)); 
    contador=0;

while(contador<12)
{
                 
                 aleatorio=rand()%[b]12[/b] + 1; 


	if(!vector[aleatorio-1])
	 {
                           printf("  %d", aleatorio);
                           vector[aleatorio-1]=1;
	               contador++;
	}
         }

printf(" backslash_n FIN (Pulsa un tecla para terminar)");
getch();

return(3986);

}


[/i]
Privagratix

Intenta técnicas de hashing y rehashing... son las mas rápidas y optimas para eso.

AvariciA

Loco, el rand ha de ser (rand()%11)+1.
Son numero del 1-12. el rand q tu expones hace numeros del 0-12 (0-12)+1=1-13.
Debe ser de 11. (0-11)+1=1-12

Cyph3r

He intentado modificarlo dado que necesito en realidad de esos 12 numeros aleatorios que cada uno de esos tenga dentro 4 numeros aleatorios.

Pero me peta

S

Cuando creas el vector indicas su longitud (n). Cuando accedes a él, lo haces de 0 a n-1 (n en total). Es por ello que peta, tienes el vector mal definido, y para colmo accedes no una, sino 2 posiciones más allá del último elemento (ahora tendrías del 0 al 10, y recorres del 0 al 12).

PS: la segunda dimensión del vector también está mal :P
Edit: No quites el código xD

Cyph3r

no eso ya lo vi lo unico que me he dado cuenta que esta mal dado que hay que hacerlo con un while la ultima parte dado que eso los for solo se ejecutaran 48 veces sin tener toda la lista completa ya que hay numeros que saldran repetidos.

aLeX

#8 eso en mi pueblo es recorrer una lista. Si cada vez que pides uno recorres los que ya tenías para ver si está o no, estás recorriendo la lista. Lo que me estás contando es recorrer el array -pero yo no he dicho en ningún momento recorrer el arrray-. El coste de tu algoritmo es mayor que el mio o el de heaton. Imaginate una lista con 2000 números donde quieres llenarla hasta 3000. En las últimas posiciones en el caso peor has de recorrerte un porrón de números.

#14 por qué fuerzas a que tu vector tenga una posición de más y no comience en 0 ?

S

#20 Porque C no es su lengua materna xD

maRc

Avaricia: rand()%11 te saca números entre el 0 y el 10. En ese caso está bien lo de Loco.

AvariciA

Alex para ti es mejor reservar posiciones de memoria para poner una simple banderita si sale esa posición, de acuerdo. Imaginate elegir un 3 numeros aleatorios diferentes entre 1-1 millon. Segun tu algoritmo genero un vector de 1millon de posiciones, q lleno con 0's, para poner una banderita en la posicion del numero obtenido, despues miro el siguiente numero a ver si hay un 0 o un 1, es decir una comparación. Bueno... la idea es para 3 posiciones q vas a llenar reservas 1 millon? Desperdiiciando memoria q lo mas seguro no vas a utilizar.

Cyph3r

ya esta ya lo he conseguido ya funciona bien y la pila lo empila todo correctamente muchas gracias a todos ;)

LOc0

#16
El resto de divir un número por x va desde 0 hasta x-1 (inclusive) Por lo tanto, el resto de dividir entre 12 va desde 0 hasta 11 (sumándole 1 nos queda 1-12).

#20
Si lo hice así es porque creía que se veía mejor, pero se puede hacer perfectamente con un elemento menos y usar vector[aleatorio-1] para acceder al array, como lo he dejado ahora. (Mira que sois tiquismiquis xD...)

#21
Es mi lengua materna, pero a veces creo que mi madre ya hablaba con algo de acento ¬ ¬...

Salu2 ;)

maRc

Hijo: printf("Hola mama!n");
Madre: Hola hijo, ¿que tal la universidad hoy?
H: scanf("%s, %s", saludo, pregunta);
if (!strcmp(pregunta,"¿que tal la universidad hoy?"))
if (ido_a_clase)
printf("Muy bienn");
else if (ido_a_biblioteca)
printf("Me he tirado toda la mañana en la bibliotecan");
else if (jugado_cartas)
printf("Esto...");

Cyph3r

te encierran de por vida.. xD

kas

@ Avaricia: La eleccion del algoritmo a usar tambien deve hacerse segun el volumen de datos a tratar. Si de momento solo hara 12 posiciones, no le saltes con lo de 1millon, obviamente eso no es efectivo.

Trisky

Por que poneis aleatorio=rand()%12 + 1;
eso es equivalente a aleatorio=random (11)+1; no??

no se me he rayado, y otra cosa que es lo del:
backslash_n
porque no lo he visto nunca....

S

"backslash_n" quiere decir "&#92;n", pero MV se come todo lo que parezca un tag.