【问题标题】:how to perform an extension of Random?如何执行随机扩展?
【发布时间】:2012-07-16 23:04:53
【问题描述】:

我正在尝试实现 Random 类的扩展。

但是这个功能会有一个特点,你可以得到一个数字跟随步骤。例如:

RandNumb(double min, double max, double step)
RandNumb(1, 10, 2) = 6
RandNumb(100, 1000, 500) = 1000
RandNumb(0.001, 0.1, 0.01) = 0.15

我的第一个想法是获取一个从 min 到 max 的随机数,并比较这是否是一个有效数字(由于 step)。如果没有,请再次生成另一个号码。

但我敢肯定,这不是一个好的表现。你怎么看?

【问题讨论】:

  • “RandNumb(1,10,2)”的有效值不会是1,3,5,7,9?
  • 哦,是的,你是对的......对不起!

标签: c# algorithm random


【解决方案1】:

只需生成从min / stepmax / step 的数字并将生成的结果乘以step。在这种情况下,每个结果都是“有效的”。

您的解决方案中的问题是 - 有可能永远不会得到按步除的“有效”数字。

【讨论】:

    【解决方案2】:

    根据问题的定义,“RandNumb (1, 10, 2)”的有效值似乎是:1, 3, 5, 7, 9。

    在这种情况下。代码如下所示:

    class Program
    {
        static void Main(string[] args)
        {
            Random rd = new Random();
            for (int i = 0; i < 10; i++)
            {
                Console.WriteLine("RandNumb(rd, 1, 10, 2)=" + RandNumb(rd, 1, 10, 2));
                Console.WriteLine("RandNumb(rd, 100, 1000, 500)=" + RandNumb(rd, 100, 1000, 500));
                Console.WriteLine("RandNumb(rd, 0.001, 0.1, 0.01) =" + RandNumb(rd, 0.001, 0.1, 0.01)); 
            }
            Console.ReadLine();
        }
    
        public static double RandNumb(Random rd, double min, double max, double step)
        {
            int range = (int)Math.Floor((max - min) / step);
            int stepCount = rd.Next(0, range + 1);
            return min + (step * stepCount);
        }
    }
    

    结果会是这样的:

    RandNumb(rd, 1, 10, 2)=3
    RandNumb(rd, 100, 1000, 500)=600
    RandNumb(rd, 0.001, 0.1, 0.01) =0,071
    RandNumb(rd, 1, 10, 2)=5
    RandNumb(rd, 100, 1000, 500)=600
    RandNumb(rd, 0.001, 0.1, 0.01) =0,041
    RandNumb(rd, 1, 10, 2)=3
    RandNumb(rd, 100, 1000, 500)=600
    RandNumb(rd, 0.001, 0.1, 0.01) =0,081
    RandNumb(rd, 1, 10, 2)=9
    RandNumb(rd, 100, 1000, 500)=600
    RandNumb(rd, 0.001, 0.1, 0.01) =0,011
    RandNumb(rd, 1, 10, 2)=7
    RandNumb(rd, 100, 1000, 500)=100
    RandNumb(rd, 0.001, 0.1, 0.01) =0,091
    RandNumb(rd, 1, 10, 2)=5
    RandNumb(rd, 100, 1000, 500)=100
    RandNumb(rd, 0.001, 0.1, 0.01) =0,001
    RandNumb(rd, 1, 10, 2)=1
    RandNumb(rd, 100, 1000, 500)=600
    RandNumb(rd, 0.001, 0.1, 0.01) =0,071
    RandNumb(rd, 1, 10, 2)=1
    RandNumb(rd, 100, 1000, 500)=600
    RandNumb(rd, 0.001, 0.1, 0.01) =0,061
    RandNumb(rd, 1, 10, 2)=5
    RandNumb(rd, 100, 1000, 500)=100
    RandNumb(rd, 0.001, 0.1, 0.01) =0,041
    RandNumb(rd, 1, 10, 2)=3
    RandNumb(rd, 100, 1000, 500)=600
    RandNumb(rd, 0.001, 0.1, 0.01) =0,021
    

    【讨论】:

      【解决方案3】:

      如何解决这个问题:

      public static class RandomExtensions
      {
          public static double RandNumb(
              this Random @this,
              double minimum, double maximum, double step)
          {
              var lowest = System.Math.Ceiling(minimum / step) * step;
              var highest = System.Math.Floor(maximum / step) * step;
              var numbers = (int)(1 + (highest - lowest) / step);
              var index = @this.Next(0, (int)numbers);
              return lowest + index * step;
          }
      }
      

      我在 LINQPad 中针对此代码进行了测试,它似乎工作正常。

      var rnd = new Random();
      
      rnd.RandNumb(1, 10, 2).Dump();
      rnd.RandNumb(100, 1000, 500).Dump();
      rnd.RandNumb(0.001, 0.1, 0.01).Dump();
      rnd.RandNumb(7, 15, 3).Dump();
      

      这是我的输出示例:

      4
      1000
      0.08
      12
      

      【讨论】:

        猜你喜欢
        • 2017-12-02
        • 1970-01-01
        • 2015-04-07
        • 1970-01-01
        • 2017-08-09
        • 2014-02-19
        • 2011-02-11
        • 2012-06-30
        • 1970-01-01
        相关资源
        最近更新 更多