【问题标题】:Generating random numbers from giving numbers in c#在c#中通过给出数字生成随机数
【发布时间】:2011-07-26 11:25:18
【问题描述】:

用户在 10 文本框中输入数字,我将它们发送到一个数组。现在我想从这个数组中生成随机数。我能做什么?

【问题讨论】:

  • 你想从数组中选择随机数吗?还是将数组用作随机数生成器的“种子”?
  • 然后看看我的回答(如果它解决了你的问题,请接受它)。
  • 等等...所以你想洗牌阵列,而不是播种 PRNG?

标签: c# arrays random


【解决方案1】:

类似这样的:

public class Randomizer<T>
{
    private readonly Random _random = new Random();
    private readonly IList<T> _numbers;
    public Randomizer(IList<T> numbers)
    {
        _numbers = numbers;
    }

    public T Next()
    {
        int idx = _random.Next(0, _numbers.Count);
        return _numbers[idx];
    }
}

用法:

var r = new Randomizer<int>(new int[] { 10, 20, 30, 40, 50 });
for (int i = 0; i < 100; i++)
     Console.Write(r.Next() + " ");

或者你想shuffle the array

[编辑]

要打乱数组,可以使用this post中显示的Fisher–Yates shuffle

// https://stackoverflow.com/questions/108819/110570#110570
public class Shuffler
{
    private Random rnd = new Random();
    public void Shuffle<T>(IList<T> array)
    {
        int n = array.Count;
        while (n > 1)
        {
            int k = rnd.Next(n);
            n--;
            T temp = array[n];
            array[n] = array[k];
            array[k] = temp;
        }
    }
}

如果你想让接口和上面的Randomizer类一样,可以修改为使用Shuffler类:

public class Randomizer<T>
{
    private readonly Shuffler _shuffler = new Shuffler();
    private readonly IList<T> _numbers;
    public Randomizer(IList<T> numbers)
    {
        _numbers = new List<T>(numbers);
        _shuffler.Shuffle(_numbers);
    }

    volatile int idx = 0;
    public T Next()
    {
        if (idx >= _numbers.Count)
        {
            _shuffler.Shuffle(_numbers);
            idx = 0;
        }

        return _numbers[idx++];
    }
}

请注意,代码不是线程安全的,因此如果可能从多个线程同时调用Next 方法,则应实施一些锁定。

【讨论】:

  • 好的,它可以工作,但我也想踢出随机发生器从数组中生成的数字,以免重复。
  • @ActuallyMAB:那么您正在谈论洗牌阵列(link to an SO answer is at the end of my post)。您能否澄清当所有数组编号都用完时会发生什么?它应该重新洗牌并重新启动吗?还是抛出异常?
  • 其实我不想重复数字。例如结果不能是这样的:5-9-5-12.
【解决方案2】:

Seed 标准的System.Random 类具有来自数组的值?如果您需要随机数依赖于所有数组项,那么只需对它们进行异或。

public static Random BuildSeededRandom(int[] data)
{
    if ( data == null || data.Length < 1 )
        return new Random();

    int xor = 0;
    foreach ( var i in data )
        xor ^= i;

    return new Random(xor);
}

【讨论】:

    猜你喜欢
    • 2013-02-28
    • 1970-01-01
    • 2019-05-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-19
    相关资源
    最近更新 更多