【问题标题】:Getting random numbers from a list of integers从整数列表中获取随机数
【发布时间】:2013-07-06 00:02:48
【问题描述】:

如果我有一个整数列表:

List<int> myValues = new List<int>(new int[] { 1, 2, 3, 4, 5, 6 } );

如何从该列表中获取 3 个随机整数?

【问题讨论】:

  • 你有没有试过解决它?你在谷歌上搜索过吗?
  • 一张便条。这个论坛不是把你的作业问题放在你的位置上,让全世界来回答它……好吗?
  • @ncourcy84 你认为这是家庭作业的依据是什么?

标签: c# random int


【解决方案1】:

一种简单的方法:

Random r = new Random();
IEnumerable<int> threeRandom = myValues.OrderBy(x => r.Next()).Take(3);

更好的方法:Fisher–Yates shuffle:

public static class EnumerableExtensions
{
    public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> source)
    {
        return source.Shuffle(new Random());
    }

    public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> source, Random rng)
    {
        if (source == null) throw new ArgumentNullException("source");
        if (rng == null) throw new ArgumentNullException("rng");

        return source.ShuffleIterator(rng);
    }

    private static IEnumerable<T> ShuffleIterator<T>(
        this IEnumerable<T> source, Random rng)
    {
        List<T> buffer = source.ToList();
        for (int i = 0; i < buffer.Count; i++)
        {
            int j = rng.Next(i, buffer.Count);
            yield return buffer[j];

            buffer[j] = buffer[i];
        }
    }
}

你如何使用它:

IEnumerable<int> threeRandom = myValues.Shuffle().Take(3);

【讨论】:

    【解决方案2】:

    最简单的方法是这样的:

    var r = new Random();
    var myValues = new int[] { 1, 2, 3, 4, 5, 6 }; // Will work with array or list
    var randomValues = Enumerable.Range(0, 3)
        .Select(e => myValues[r.Next(myValues.Length)]);
    

    但更好的方法是,如果要确保没有重复项,请使用洗牌算法,例如 Fisher-Yates algorithm,然后取前 3 项:

    public static T[] Shuffle<T>(IEnumerable<T> items)
    {
        var result = items.ToArray();
        var r = new Random();
        for (int i = items.Length; i > 1; i--)
        {
            int j = r.Next(i);
            var t = result[j];
            result[j] = result[i - 1];
            result[i - 1] = t;
        }
    
        return result;
    }
    
    var myValues = new int[] { 1, 2, 3, 4, 5, 6 }; // Will work with any enumerable
    var randomValues = myValues.Shuffle().Take(3);
    

    【讨论】:

    • 但是由于排列是随机生成的,所以会重复。如果我想获取一个 n 位数字的所有排列并将其保存在某个地方怎么办。 ?
    【解决方案3】:

    或者这个:

    myList.OrderBy(x => Guid.newGuid()).Take(3)
    

    【讨论】:

      【解决方案4】:

      other answerthis answer 结合使用可导致以下结果:

      var rand = new Random();
      var numbers = Enumerable.Range(1, 6).OrderBy(i => rand.Next()).ToList();
      

      在这种情况下,1 是起始值(包括),6 是要生成的整数数。

      【讨论】:

        【解决方案5】:

        有很多方法!一个简单的谷歌可以为您获取数百个答案。但是,您可以这样做!

        myList.OrderBy(x => rnd.Next()).Take(3)
        

        【讨论】:

          【解决方案6】:

          使用以下代码获取号码:

          int k = 3; // items to select
          var items = new List<int>(new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 });
          var selected = new List<int>();
          var neededItem = k;
          var availableItem = items.Count;
          var rand = new Random();
          while (selected.Count < k) {
             if( rand.NextDouble() < neededItem / availableItem ) {
                selected.Add(items[availableItem-1])
                neededItem--;
             }
             availableItem--;
          }
          

          【讨论】:

          • 这可以多次选择同一个项目。此外,无需获取随机双精度并对其进行操作,只需使用 Next 获取两个数字之间的随机 int。
          【解决方案7】:
          int[] x = {1,2,3,4};
          
          string result =  Convert.ToString(x[(new Random()).Next(4)]);
          

          【讨论】:

            猜你喜欢
            • 2023-03-11
            • 2021-09-21
            • 1970-01-01
            • 2011-08-11
            • 2018-11-06
            • 2023-03-03
            • 1970-01-01
            • 1970-01-01
            • 2015-01-27
            相关资源
            最近更新 更多