2010-06-16 35 views
6

que tiene un problema al generar números aleatorios en un bucle. Puede evitarlo utilizando Thread.Sleep pero después de una solución más elegante.Número aleatorio en un bucle

for ... 
    Random r = new Random(); 
    string += r.Next(4); 

va a terminar con 11111 ... 222 ... etc

Sugerencias?

+1

Si este ciclo tiene más de unas pocas iteraciones, querrá abandonar la concatenación de cadenas a favor de un objeto 'StringBuilder'. –

+5

@Anthony: No, necesita usar _more_ vez cada iteración. –

+0

@Henk ... Obviamente. Podría sugerir un bucle anidado para concatenaciones múltiples de un solo espacio, seguido de inmediato por el reemplazo del espacio simple con una cadena. Vacío. –

Respuesta

50

Mueva la declaración del generador de números aleatorios fuera del ciclo.

La generación de números aleatorios comienza desde un valor de inicialización. Si la misma semilla se usa repetidamente, se genera la misma serie de números. Una forma de producir secuencias diferentes es hacer que el valor inicial sea dependiente del tiempo, produciendo así una serie diferente con cada instancia nueva de Aleatorio. Por defecto, el constructor sin parámetros de la clase Random utiliza el reloj del sistema para generar su valor semilla, ...

Source

Al tener la declaración en el bucle que está llamando al constructor efectivamente con el mismo valor una y otra vez, por lo tanto, obtienes los mismos números.

Así que el código debe convertirse:

Random r = new Random(); 
for ... 
    string += r.Next(4); 
9
Random r = new Random(); 
for ... 
    string += r.Next(4); 

new Random() inicializará el (pseudo) generador de números aleatorios con una semilla en base a la fecha y hora actuales. Por lo tanto, dos instancias de Random creadas en la misma fecha y hora producirán la misma secuencia de números.

Creó un nuevo generador de números aleatorios en cada iteración y luego tomó el primer valor de esa secuencia. Como los generadores de números aleatorios eran iguales, el primer valor de sus secuencias era el mismo. Mi solución creará un generador de números aleatorios y luego devolverá el primer, segundo, etc. valor de la secuencia (que será diferente).

2

Debería utilizar la misma instancia Aleatoria en todo momento en lugar de crear una nueva cada vez.

Como lo tienes:

for ... 
    Random r = new Random(); 
    string += r.Next(4); 

el valor de inicialización es el mismo para cada uno (el valor predeterminado es la fecha y hora actual) por lo que el valor devuelto es el mismo.

Mediante la reutilización de una sola instancia aleatoria de este modo:

Random r = new Random() 
for ... 
    string += r.Next(4); 

Cada vez que llame r.Next(4) los valores se actualizan (básicamente una semilla diferente para cada llamada).

3

Mueva el Random r = new Random(); fuera del bucle y simplemente llame al siguiente dentro del bucle.

+1

Debería haber recargado la página. LOL todo el mundo tenía la misma respuesta – used2could

+0

la pregunta es "DENTRO DEL BUCLE" – Mironline

+0

@Mironline tal vez no leyó mi respuesta completa, también declaro que debo dejar "al lado dentro del ciclo". La respuesta aceptada fue exactamente como la describí, así que supongo que se ajusta a la solicitud del OP. – used2could

2

me encontré con una página en chino que dijo lo mismo con el tiempo: http://godleon.blogspot.hk/2007/12/c.html, se dijo que si se escribe así:

Random random = new Random(Guid.NewGuid().GetHashCode());

Usted puede obtener un número aleatorio incluso en un lazo! ¡Solucionó mi pregunta también!

+0

por qué hacerlo lento, solo 'Guid.NewGuid(). GetHashCode()' será suficiente – nawfal

+0

@nawfal Realmente no entiendo lo que dices ?? !! ¿No hice eso? –

+0

Quise decir 'Guid.NewGuid(). GetHashCode()' será más rápido que 'new Random (Guid.NewGuid(). GetHashCode())'. Ambos dan enteros aleatorios – nawfal

Cuestiones relacionadas