Подтвердить что ты не робот

Как получить случайное число из диапазона, исключая некоторые значения

В С#, как мне получить случайное число из диапазона значений - например, 1..100, но это число не должно быть в каком-то определенном списке значений, например 5, 7, 17, 23?

4b9b3361

Ответ 1

Поскольку никто не опубликовал какой-либо пример кода:

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);
}

Здесь мышление:

  • Создайте хэш-номер чисел, которые вы хотите исключить
  • Создайте коллекцию всех чисел 0-100, которые не входят в ваш список чисел, чтобы исключить их с помощью LINQ.
  • Создайте случайный объект.
  • Используйте объект Random, чтобы дать вам число от 0 до количества элементов в вашем диапазоне чисел (включительно).
  • Возвращает номер в этом индексе.

Ответ 2

Если вам интересно, Big O, проверьте этот алгоритм. Он предполагает, что массив исключенных значений сортируется в порядке возрастания и содержит значения в диапазоне 0 и n-1 (включительно).

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;
}

Если вы вызываете его с помощью:

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

он вернет одно из следующих значений: 0, 1, 2, 5, 7.

Ответ 3

Это метод расширения, который я использую:

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;
    }

Ответ 4

вы можете использовать оператор do-while для выбора другого Random, если он равен числу, которое вы хотите исключить. этот код должен исключить номер, который вы выбрали до

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

number = newNumber;

Ответ 5

Поместите разрешенные числа в массив, сгенерируйте случайное целое число от 0 до длины этого массива минус единица. Используйте это целое число как индекс, чтобы получить случайное число из массива разрешенных чисел.


Если исходный массив содержит большие объекты вместо чисел, то создание другого массива путем глубокого копирования разрешенных объектов не будет эффективным. В этом случае массив разрешенных объектов должен содержать только указатель, ссылку или индекс для объектов в исходном массиве. В этом случае вы генерируете случайное целое число, чтобы выбрать один элемент этого массива, и используйте этот указатель /reference/index для получения выбранного объекта из исходного массива.

Здесь - рабочий пример для общего случая (только одно возможное решение!):

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));
    }
}

Ответ 6

Создайте массив, содержащий все нужные вам номера (или любой другой контейнер, на котором используется ваш язык) минус весь номер, который вы не хотите, и произвольно выберите из массива.

Ответ 7

Используйте функцию для генерации случайных чисел от 1 до 100, чем запись оператора if, например. если случайное число равно 5, 7, 17, 23, сгенерируйте случайное число снова, иначе используйте случайное число, которое было сгенерировано в первую очередь.

Ответ 8

Это то, что я делаю в этой ситуации, это не идеально, но хорошо работает для меня. Обычно я делаю это только для 1 числа, но это так, как это может быть для группы исключенных чисел:

Скажем, я хочу исключить [5, 7, 17, 23] из случайного числа от 1 до 100. У меня всегда есть замена для каждого из исключенных чисел, таких как [6, 8, 18, 24]. Если случайное число попадает в любой из исключенных номеров, я заменяю его его заменой.

Я пришел сюда, чтобы найти лучшее решение, но я не мог найти никого, поэтому я попал в раздел моих.