2011-07-14 13 views
20

¿Cómo hago para elegir una cadena aleatoria de mi matriz pero no la misma?Seleccionar cadena aleatoria del arreglo

string[] names = { "image1.png", "image2.png", "image3.png", "image4.png", "image5.png" }; 

¿Esto es posible? Estaba pensando en usar

return strings[random.Next(strings.Length)]; 

Pero esto tiene la posibilidad de devolver la misma cuerda dos veces. ¿O estoy equivocado acerca de esto? ¿Debo usar algo más como List para lograr esto? Cualquier comentario es bienvenido

+5

Parece que * shuffle * la matriz, y luego iterar sobre la matriz normalmente. Hay muchas preguntas mezcladas en Stack Overflow. –

+1

@Atrljoe - ¿Comprende que devolver la misma cadena dos veces sería un resultado aleatorio, verdad? Si no desea obtener el mismo resultado dos veces, lo que desea no se puede describir como un resultado aleatorio. –

+0

@Ramhound, por supuesto, sería aleatorio. No sería una secuencia de eventos * independientes *, pero aún sería aleatorio. – CodesInChaos

Respuesta

33

La manera más simple (pero lenta para listas grandes) sería usar un contenedor redimensionable como List y eliminar un elemento después de haberlo seleccionado. Me gusta:

var names = new List<string> { "image1.png", "image2.png", "image3.png", "image4.png", "image5.png" }; 

int index = random.Next(names.Count); 
var name = names[index]; 
names.RemoveAt(index); 
return name; 

Cuando su lista esté vacía, se tomaron todos los valores.

Una manera más rápida (especialmente si su lista es larga) sería usar un algoritmo de mezcla en su lista. A continuación, puede mostrar los valores de uno en uno. Sería más rápido porque eliminar del extremo de un List generalmente es mucho más rápido que eliminarlo del medio. En cuanto a la mezcla, puede echar un vistazo al this question para obtener más detalles.

+1

@ samb8s Sí, pero era más rápido :) –

+2

Tenga en cuenta que esto es potencialmente una mala idea si la lista es larga. La eliminación de un elemento desde cerca del comienzo de una larga lista tiene que mover todos los elementos después de ella. –

+0

@Eric De hecho, lo edité para que quede más claro. –

2

Lo mejor que puede hacer es simplemente crear una lista duplicada, y luego, al seleccionar al azar una cadena, puede eliminarla de la lista duplicada para que no pueda elegirla dos veces.

+0

también me ganaste – samb8s

2

La lógica se puede utilizar es el siguiente:

1) Pick un entero aleatorio en el rango de igual a la longitud de la matriz. Puedes hacer esto usando la clase System.Random.

2) Utilice la cadena correspondiente a ese índice de matriz

3) Eliminar el elemento con el que el índice de la matriz (puede ser más fácil con una lista)

A continuación, se puede recoger una y la misma cuerda no aparecerá La matriz será un elemento más corto.

1

Debería realizar un seguimiento de las que ha utilizado, preferiblemente en un List si no desea/no puede modificar la matriz original. Use un bucle while para verificar que no se haya utilizado y luego agréguelo a la lista "usado".

+4

OK, supongamos que hay mil elementos en la lista original y 999 artículos en la lista "usado". ¿Tu plan es seguir generando números aleatorios hasta que llegues a uno entre mil? Su algoritmo de selección de lista será cada vez más lento. Este es un algoritmo pobre para listas más largas. –

5

Puede barajar la matriz en un primer paso, y luego simplemente iterar sobre la matriz mezclada.
Esto tiene la ventaja de ser O (n) en comparación con O (n^2) las implementaciones basadas en RemoveAt tienen. Por supuesto, esto no importa mucho para arreglos cortos.

Comprobar la respuesta de Jon Skeet a la siguiente pregunta de un bien (todos los pedidos son igualmente probables) la implementación de shuffe: Is using Random and OrderBy a good shuffle algorithm?

1
//SET LOWERLIMIT 
cmd = new SqlCommand("select min(sysid) as lowerlimit from users", cs); 
int _lowerlimit = (int) cmd.ExecuteScalar(); 
lowerlimit = _lowerlimit; 

//SET UPPERLIMIT 
cmd = new SqlCommand("select max(sysid) as upperlimit from users", cs); 
int _upperlimit = (int) cmd.ExecuteScalar(); 
upperlimit = _upperlimit; 

//GENERATE RANDOM NUMBER FROM LOWERLIMIT TO UPPERLIMIT 
Random rnd = new Random(); 
int randomNumber = rnd.Next(lowerlimit, upperlimit+1); 

//DISPLAY OUTPUT 
txt_output.Text += randomNumber; 
26

probar este código de abajo

string[] Titles = { "Excellent", "Good", "Super", "REALLY GOOD DOCTOR!", "THANK YOU!", "THE BEST", "EXCELLENT PHYSICIAN", "EXCELLENT DOCTOR" }; 

comments_title.Value=Titles[new Random().Next(0,Titles.Length) ] ; 
+3

En el futuro, intenta agregar un poco más de descripción a tus publicaciones. ¡Buena idea! :) – davehale23

+0

Siempre pensé que todos los comentarios eran honestos y no automáticos y que los que recibían buenas críticas en realidad eran buenos. – Zurechtweiser

+1

si elige el valor máximo (Titles.Length) esto causará IndexOutOfRangeException. De lo contrario, funciona bien. (Solo haga Titles.Length - 1) – Gober

0

Utilice el método de utilidad más adelante

public static class ListExtensions 
{ 
    public static T PickRandom<T>(this List<T> enumerable) 
    { 
     int index = new Random().Next(0, enumerable.Count()); 
     return enumerable[index]; 
    } 
} 

Luego llame al siguiente formulario

string[] fruitsArray = { "apple", "orange"}; 
string inputString = fruitsArray.ToList().PickRandom(); 
Cuestiones relacionadas