вектор лотереи с циклом без дубликатов [дубликат]

Существует много причин. Мой любимый - когда вам нужно изменить поведение или отрегулировать то, что вы можете установить для переменной. Например, скажем, у вас был метод setSpeed ​​(int speed). Но вы хотите, чтобы вы могли установить максимальную скорость 100. Вы бы сделали что-то вроде:

public void setSpeed(int speed) {
  if ( speed > 100 ) {
    this.speed = 100;
  } else {
    this.speed = speed;
  }
}

Теперь, что, если EVERYWHERE в вашем коде вы использовали публичное поле, а затем вы поняли, что вам нужно выше требования? Получите удовольствие, охотясь за каждым использованием публичного поля, а не просто изменяя свой сеттер.

Мои 2 цента:)

18
задан Michael Petrotta 23 January 2013 в 07:57
поделиться

10 ответов

Я регулярно звоню в NewNumber (), но проблема в том, что я часто получаю повторяющиеся числа.

Random.Next не гарантирует, что число будет уникальным. Также ваш диапазон от 0 до 10, и, скорее всего, вы получите повторяющиеся значения. Возможно, вы можете настроить список int и вставить случайные числа в список после проверки, не содержит ли он дубликата. Что-то вроде:

public Random a = new Random(); // replace from new Random(DateTime.Now.Ticks.GetHashCode());
                                // Since similar code is done in default constructor internally
public List<int> randomList = new List<int>();
int MyNumber = 0;
private void NewNumber()
{
    MyNumber = a.Next(0, 10);
    if (!randomList.Contains(MyNumber))
        randomList.Add(MyNumber);
}
17
ответ дан Habib 26 August 2018 в 04:05
поделиться

Попробуйте следующее:

private void NewNumber()
  {
     Random a = new Random(Guid.newGuid().GetHashCode());
     MyNumber = a.Next(0, 10);
  }

Некоторые объяснения:

Guid: base здесь : представляет глобально уникальный идентификатор (GUID)

Guid.newGuid() создает уникальный идентификатор, такой как "936DA01F-9ABD-4d9d-80C7-02AF85C822A8"

, и он будет уникальным во всей базе вселенной здесь

Хэш-код здесь создает уникальное целое из нашего уникального идентификатора

, поэтому Guid.newGuid().GetHashCode() дает нам уникальное число, и случайный класс будет генерировать реальные случайные числа, бросая этот

-4
ответ дан AliTheOne 26 August 2018 в 04:05
поделиться

В зависимости от того, что вы действительно после того, как вы можете сделать что-то вроде этого:

using System;
using System.Collections.Generic;
using System.Linq;

namespace SO14473321
{
    class Program
    {
        static void Main()
        {
            UniqueRandom u = new UniqueRandom(Enumerable.Range(1,10));
            for (int i = 0; i < 10; i++)
            {
                Console.Write("{0} ",u.Next());
            }
        }
    }

    class UniqueRandom
    {
        private readonly List<int> _currentList;
        private readonly Random _random = new Random();

        public UniqueRandom(IEnumerable<int> seed)
        {
            _currentList = new List<int>(seed);
        }

        public int Next()
        {
            if (_currentList.Count == 0)
            {
                throw new ApplicationException("No more numbers");
            }

            int i = _random.Next(_currentList.Count);
            int result = _currentList[i];
            _currentList.RemoveAt(i);
            return result;
        }
    }
}
1
ответ дан Andrew Savinykh 26 August 2018 в 04:05
поделиться

Вы можете использовать базовые случайные функции C #

Random ran = new Random();
int randomno = ran.Next(0,100);

, теперь вы можете использовать значение в случайном порядке во всем, что хотите, но имейте в виду, что это создаст случайное число между 0 и 100 Только и вы можете расширить его до любой цифры.

-2
ответ дан emix 26 August 2018 в 04:05
поделиться

Проверьте этот готовый к использованию метод: Дайте в диапазоне & amp; количество номеров, которое вы хотите получить.

public static int[] getUniqueRandomArray(int min, int max, int count) {
    int[] result = new int[count];
    List<int> numbersInOrder = new List<int>();
    for (var x = min; x < max; x++) {
        numbersInOrder.Add(x);
    }
    for (var x = 0; x < count; x++) {
        var randomIndex = Random.Range(0, numbersInOrder.Count);
        result[x] = numbersInOrder[randomIndex];
        numbersInOrder.RemoveAt(randomIndex);
    }

    return result;
}
0
ответ дан Evren Ozturk 26 August 2018 в 04:05
поделиться

Вы также можете использовать dataTable, сохраняя каждое случайное значение, а затем просто выполняйте случайный метод, а! = значения в dataColumn

-1
ответ дан Herman Vercuiel 26 August 2018 в 04:05
поделиться

Вы можете попробовать перетасовать массив возможных int, если ваш диапазон - только от 0 до 9. Это добавляет преимущество предотвращения любых конфликтов в генерации числа.

var nums = Enumerable.Range(0, 10).ToArray();
var rnd = new Random();

// Shuffle the array
for (int i = 0;i < nums.Length;++i)
{
    int randomIndex = rnd.Next(nums.Length);
    int temp = nums[randomIndex];
    nums[randomIndex] = nums[i];
    nums[i] = temp;
}

// Now your array is randomized and you can simply print them in order
for (int i = 0;i < nums.Length;++i)
    Console.WriteLine(nums[i]);
13
ответ дан itsme86 26 August 2018 в 04:05
поделиться

ПРИМЕЧАНИЕ. Я не рекомендую это :). Вот также «oneliner»:

//This code generates numbers between 1 - 100 and then takes 10 of them.
var result = Enumerable.Range(1,101).OrderBy(g => Guid.NewGuid()).Take(10).ToArray();
8
ответ дан JOSEFtw 26 August 2018 в 04:05
поделиться

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

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

Ниже приведена реализация Fisher-Yates Shuffle

g0] (также известный как Knuth Shuffle). (Прочитайте раздел «ошибки реализации» этой ссылки (найдите «всегда выбирая j из всего диапазона допустимых индексов массива на каждой итерации»), чтобы увидеть некоторое обсуждение того, что не так с другой реализацией, размещенной здесь.)

using System;
using System.Collections.Generic;

namespace ConsoleApplication2
{
    static class Program
    {
        static void Main(string[] args)
        {
            Shuffler shuffler = new Shuffler();
            List<int> list = new List<int>{ 1, 2, 3, 4, 5, 6, 7, 8, 9 };
            shuffler.Shuffle(list);

            foreach (int value in list)
            {
                Console.WriteLine(value);
            }
        }
    }

    /// <summary>Used to shuffle collections.</summary>

    public class Shuffler
    {
        /// <summary>Creates the shuffler with a <see cref="MersenneTwister"/> as the random number generator.</summary>

        public Shuffler()
        {
            _rng = new Random();
        }

        /// <summary>Shuffles the specified array.</summary>
        /// <typeparam name="T">The type of the array elements.</typeparam>
        /// <param name="array">The array to shuffle.</param>

        public void Shuffle<T>(IList<T> array)
        {
            for (int n = array.Count; n > 1; )
            {
                int k = _rng.Next(n);
                --n;
                T temp = array[n];
                array[n] = array[k];
                array[k] = temp;
            }
        }

        private System.Random _rng;
    }
}
8
ответ дан Matthew Watson 26 August 2018 в 04:05
поделиться

И вот моя версия поиска N случайных уникальных чисел с использованием HashSet. Выглядит довольно просто, поскольку HashSet может содержать только разные элементы. Это интересно - будет ли это быстрее, чем использовать List или Shuffler?

using System;
using System.Collections.Generic;

namespace ConsoleApplication1
{
    class RnDHash
    {
        static void Main()
        {
            HashSet<int> rndIndexes = new HashSet<int>();
            Random rng = new Random();
            int maxNumber;
            Console.Write("Please input Max number: ");
            maxNumber = int.Parse(Console.ReadLine());
            int iter = 0;
            while (rndIndexes.Count != maxNumber)
            {
                int index = rng.Next(maxNumber);
                rndIndexes.Add(index);
                iter++;
            }
            Console.WriteLine("Random numbers were found in {0} iterations: ", iter);
            foreach (int num in rndIndexes)
            {
                Console.WriteLine(num);
            }
            Console.ReadKey();
        }
    }
}
0
ответ дан Vasily Novsky 26 August 2018 в 04:05
поделиться
Другие вопросы по тегам:

Похожие вопросы: