Как сгенерировать случайное число в интервале без повторений?
Нужно сгенерировать случайное число в интервале от 1 до 30 включительно без повторений. Как это сделать?
Ответы (2 шт):
Автор решения: Andrei Khotko
→ Ссылка
Основная идея: Записываем уникальные числа в список. Генерируем число от 0 до N, где N - длина списка чисел. После генерации удаляем из списка сгенерированное число.
private static void Main(string[] args)
{
var random = new Random();
var numbers = Enumerable.Range(1, 30).ToList();
var numbersCopy = new List<int>(numbers);
for (var i = 0; i < numbers.Count; i++)
{
var pickIndex = random.Next(numbersCopy.Count);
var randNumber = numbersCopy[pickIndex];
Console.WriteLine($"Generated value: {randNumber}");
numbersCopy.RemoveAt(pickIndex);
}
Console.ReadLine();
}
Внимание: Повторять такую генерацию можно до тех пор, пока числа не закончатся в списке. Далее необходимо будет заново создавать список чисел.
Написал класс, который генерирует числа без повторений до тех пор, пока они не закончатся, после чего по второму кругу генерирует эти же числа без повторений и т.д.
public class DistinctRandom
{
private static readonly Random _random = new Random();
private readonly int[] _numbers;
private List<int> _notGeneratedNumbers;
public DistinctRandom(int[] generateFrom)
{
_numbers = generateFrom;
_notGeneratedNumbers = new List<int>(generateFrom);
}
public int Next()
{
if (!_notGeneratedNumbers.Any())
{
_notGeneratedNumbers = new List<int>(_numbers);
}
var pickIndex = _random.Next(_notGeneratedNumbers.Count);
var randNumber = _notGeneratedNumbers[pickIndex];
_notGeneratedNumbers.RemoveAt(pickIndex);
return randNumber;
}
}
Использование:
private static void Main(string[] args)
{
var numbers = Enumerable.Range(1, 30).ToArray();
var distinctRandom = new DistinctRandom(numbers);
var n = 50;
for (var i = 0; i < n; i++)
{
var randNumber = distinctRandom.Next();
Console.WriteLine($"Generated number: {randNumber}");
}
Console.ReadLine();
}
Автор решения: aepot
→ Ссылка
Random random = new Random();
int n = 30;
int[] array = Enumerable.Range(1, n).ToArray();
for (int i = 0; i < n; n++)
{
int j = random.Next(n);
int x = array[i];
array[i] = array[j];
array[j] = x;
}
Console.WriteLine(string.Join(" ", array));
Вывод
5 24 16 1 8 17 14 23 12 9 7 21 2 11 4 30 28 10 13 29 3 25 20 6 15 18 22 19 26 27