En C#, ¿cómo puedo obtener un número aleatorio a partir de una serie de valores como la 1..100, pero ese número no debe estar en una lista específica de los valores, como 5, 7, 17, 23?

  • ¿en qué idioma estás usando??
  • Estoy usando c#…
InformationsquelleAutor tenthplanet0 | 2013-08-28

8 Comentarios

  1. 32

    Ya que nadie ha publicado algún código de ejemplo:

    private int GiveMeANumber()
    {
        var exclude = new HashSet<int>() { 5, 7, 17, 23 };
        var range = Enumerable.Range(1, 100).Where(i => !exclude.Contains(i));
    
        var rand = new System.Random();
        int index = rand.Next(0, 100 - exclude.Count);
        return range.ElementAt(index);
    }

    Aquí está el pensamiento:

    1. Construir un Hashset de números que usted desea excluir
    2. Crear una colección de todos los números de 0 a 100 que no están en su lista de números de excluir con un poco de LINQ.
    3. Crear un objeto random.
    4. Utilizar el objeto Random para darle un número entre 0 y el número de elementos en el rango de los números (inclusive).
    5. Devolver el número en el índice.
    • Si usted hace exclude un HashSet en lugar de un List, y el uso 100 - exclude.Count en lugar de range.Count(), esto puede ser aún más eficiente 🙂
    • Excelentes puntos – he editado en. También me di cuenta de que OP quería números entre 1 y 100, y no de 0 y 100 como yo originalmente.
    • Estoy recibiendo el error en la línea 7 : int índice = rand.Siguiente(0,100-excluir.Count); porque de (.Next()), en el que el sistema de la directiva puedo encontrar esto? el error que estoy recibiendo es error CS1061: Tipo de UnityEngine.Random' does not contain a definition for Siguiente’ y ningún método de extensión Next' of type UnityEngine.Al azar » puede ser encontrado (¿falta una directiva using o una referencia de ensamblado?)
    • Es en el espacio de nombres System – he editado el código para calificar plenamente que Clase al Azar que usted necesita.
    • gracias por el código, Pero no estoy recibiendo números únicos
    • 6, 4, 19, 4, 11, 14, 14, 14, 4, 4, 19, 4, 17, 6, 17, 18, 15, 17, 15, 13 son los números que me dieron cuando cambia el rango de 1 a 20
    • Nunca se mencionó que quería resultados únicos, el código que me dieron aquí sólo se genera un número único. Todo depende de cómo se está generando sus números: si usted está usando LINQ podría ser sólo una cuestión de agregar .Distinct(), o si vas a agregar sus números a un List<int> o similar, ¿cómo sobre la adición de ellos a un Hashset<int> (como en la respuesta aquí, sólo permite valores únicos) en su lugar? Si esto no lo cubre, te sugiero publicar el código que has escrito para generar la secuencia como una nueva pregunta.
    • ohh lo siento… sí, yo no he mencionado que quiero resultados únicos…
    • Si el rango es muy grande y los números posibles para excluir es muy pequeño, esto es bastante ineffficient porque tienes que crear una lista enorme/set primero para seleccionar un número. A continuación, un whilebucle que se ejecuta si el número aleatorio generado debe ser excluido sería mucho más eficiente(trial&error). Tenga en cuenta que ElementAt necesidades para enumerar toda la secuencia para encontrar el índice.
    • Justo lo suficiente, pero yo no podía pensar en una mejor manera de hacer esto hace cuatro años – siéntase libre de utilizar uno de los potencialmente más eficientes respuestas publicadas en los años desde entonces!

  2. 4

    Si usted se preocupa por Grande O, echa un vistazo a este algoritmo. Se supone que la exclusión de los valores de la matriz se ordenan en orden ascendente y contiene los valores dentro de 0 y n-1 rango (inclusive).

    public static int random_except_list(int n, int[] x) 
    {
        Random r = new Random();
        int result = r.Next(n - x.Length);
    
        for (int i = 0; i < x.Length; i++) 
        {
            if (result < x[i])
                return result;
            result++;
        }
        return result;
    }

    Si usted lo llama con:

    random_except_list(8, new int[]{3,4,6})

    va a devolver uno de los siguientes valores: 0, 1, 2, 5, 7.

    • Creo que es la mejor manera para el rendimiento. Gracias
  3. 2

    puede utilizar un do-while para elegir otro al Azar si es igual a lo que el número que desea excluir.
    este código es para excluir el número que se recogen antes de

        int newNumber;
    do {
        newNumber = Random.Range (0, 100);
    } while(number == newNumber);
    
    number = newNumber;
  4. 1

    Esto es lo que quiero hacer en esta situación, no es perfecto, pero funciona bien para mí. Normalmente lo hago sólo para 1 número, pero esta es la forma en que puede ser para un grupo de excluidos números:

    Digamos que yo quiero para excluir [5, 7, 17, 23] a partir de un aleatorio entre 1 y 100.
    Siempre tengo una sustitución para cada uno de los excluidos de los números, tales como [6, 8, 18, 24]. Si el número aleatorio cae en cualquiera de los excluidos de los números, puedo reemplazar con su sustitución.

    Vine aquí en busca de una mejor solución, pero no pude encontrar ninguna, así que terminó compartir la mía.

  5. 1

    Esta es la Extensión del método que yo uso:

    Random random = new Random();
    public static int RandomNumber(int minN, int maxN, IEnumerable<int> exNumbers)
        {
            int result = exNumbers.First(); 
            while (exNumbers.ToList().Contains(result))
            {
                result = random.Next(minN, maxN + 1);
            }
            return result;
        }
  6. 0

    Crear un array que contiene todos los números que desee (o cualquier recipiente de su idioma usa) menos todo el número que usted no desee y seleccione al azar de la matriz.

    • Gracias por la lógica…. mi matriz crecerá. Se esta lógica de ser rentable en caso de gran comparaciones?
  7. 0

    Utilizar una función para generar números aleatorios entre 1 y 100, de escribir una sentencia if por ejemplo, si el número aleatorio es igual a 5, 7, 17, 23, generar el número aleatorio de nuevo, de otra manera utilizar el número aleatorio que se genera en el primer lugar.

    • si mi lista va a ser mayor que el? Creo que de nuevo y de nuevo ir en la verificación de si las declaraciones
  8. 0

    Poner los números permitidos en una matriz, genera un entero aleatorio entre 0 a la longitud de esta matriz de menos uno. El uso de esta entero como un índice para obtener el número aleatorio propio de la matriz de números permitidos.


    Si la matriz original contiene objetos de gran tamaño en lugar de números, a continuación, hacer otra matriz profunda de copiar el permitió que los objetos no serán eficaces. En este caso, la matriz de objetos sólo debe contener un puntero, una referencia, o un índice de los objetos en la matriz original. En este caso se genera un entero aleatorio para seleccionar un elemento de esta matriz, y utilizar este puntero/referencia/índice para obtener el objeto seleccionado a sí mismo de la original matriz.

    Aquí es un ejemplo de trabajo para el caso general (sólo una de las posibles soluciones!):

    using System;
    using System.Collections.Generic;
    public static class RandomElementSelector
    {
    public static IList<T> CollectAllowedElements<T>(IList<T> allElements, IList<T> excludedElements)
    {
    List<T> allowedElements = new List<T>();
    foreach (T element in allElements)
    if (!excludedElements.Contains(element))
    allowedElements.Add(element);
    return allowedElements;
    }
    public static T SelectRandomElement<T>(IList<T> allowedElements)
    {
    Random random = new Random();
    int randomIndex = random.Next(allowedElements.Count);
    return allowedElements[randomIndex];
    }
    public static T SelectRandomElement<T>(IList<T> allElements, IList<T> excludedElements)
    {
    IList<T> allowedElements = CollectAllowedElements(allElements, excludedElements);
    return SelectRandomElement(allowedElements);
    }
    }
    public class Test
    {
    public static void Main()
    {
    const int N = 100;
    //Example #1
    int[] allNumbers = new int[N];
    for (int i = 0; i < allNumbers.Length; ++i)
    allNumbers[i] = i + 1;
    int[] excludedNumbers = { 5, 7, 17, 23 };
    Console.WriteLine(RandomElementSelector.SelectRandomElement(allNumbers, excludedNumbers));
    //Example #2
    List<string> allStrings = new List<string>();
    for (int i = 0; i < N; ++i)
    allStrings.Add("Item #" + (i + 1));
    string[] excludedStrings = { "Item #5", "Item #7", "Item #17", "Item #23" };
    Console.WriteLine(RandomElementSelector.SelectRandomElement(allStrings, excludedStrings));
    }
    }
    • Gracias por la respuesta. Puede usted ser más específico? Puedo obtener el código para esto? como mi matriz puede crecer enorme
    • Seguro. He añadido un poco de código a mi respuesta.
    • hey kol, gracias por su tiempo. Me han pedido una pregunta más en el otro enlace. Quisiera tener solución si ganas…stackoverflow.com/questions/18568050/…

Dejar respuesta

Please enter your comment!
Please enter your name here