【问题标题】:Random even odd number generation in c#c#中的随机偶奇数生成
【发布时间】:2020-12-05 11:33:05
【问题描述】:

我有一个带有两个参数的函数,比如 a 和 b。所以基本上,每当我调用这个方法 50% 次它应该返回 a 和 50% 次它应该返回 b。

public string Randomization(string a, string b)

我想过使用随机数生成来做到这一点,如果生成的数字是偶数,则返回 a,如果是奇数,则返回 b。我怎么能做到这一点,或者还有其他简单的方法吗?

【问题讨论】:

  • 随机生成 0 或 1 并执行 if-else 语句。这可能会对您有所帮助:stackoverflow.com/questions/1493051/random-number-0-or-1
  • 50% 的时间不会帮助随机。按照你的逻辑说,如果随机数连续给出 4 个偶数,它的 100%a 和 0%b。所以,如果 50% 是硬性规定,那么你需要保留一个计数器和 /2 来确定它应该是 a 还是 b。
  • 需要多少次试验才能产生这 50%?以及百分比需要有多准确。要求精确地 50% 意味着实现它的唯一方法就是交替返回ab
  • @Damien_The_Unbeliever 不,不需要交替。您可以将ab 中的n / 2 放在一个列表中,然后随机播放。生成的序列将具有随机顺序,但仍具有 50/50 的结果分布。

标签: c# .net random


【解决方案1】:

你可以像下面这样使用NextDouble()

public string Randomization(string a, string b)
{
    return new Random().NextDouble() < 0.5 ? a : b;
}

该解决方案也适用于Next(int maxValue)。但是,如果该方法被调用的次数足够多,因此性能可能值得考虑,NextDouble() 将是一个更好的选择。

以下是这两种方法的源代码:

public virtual int Next(int maxValue) {
    if (maxValue<0) {
        throw new ArgumentOutOfRangeException("maxValue", Environment.GetResourceString("ArgumentOutOfRange_MustBePositive", "maxValue"));
    }
    Contract.EndContractBlock();
    return (int)(Sample()*maxValue);
}

public virtual double NextDouble() {
    return Sample();
}

这是参考:https://github.com/Microsoft/referencesource/blob/master/mscorlib/system/random.cs#L181

关于性能的另一点。您应该将Random 类的实例化移到Randomization() 方法之外。

【讨论】:

    【解决方案2】:

    0 到 1 之间的简单随机数就可以了。

    private Random _rnd = new();
    public string Randomization(string a, string b) {
        if (_rnd.Next(2) == 0) {
            return a;
        }
        return b;
    }
    

    Random.Next

    编辑:最好在函数之外创建一次 Random 对象(出于多种原因)。

    【讨论】:

    • 仅:在方法之外实例化 Random 一次,或者如果经常调用,您可能会生成相同的数字
    • @HansKesting 你说得对,我没有添加它是为了简单,但我会编辑
    【解决方案3】:

    您还可以使用采用字符串数组的方法。然后,如果您有更多字符串,则不必创建新方法。

    此外,您应该将Random 对象设为属性或字段。否则,如果您经常在几毫秒内调用该方法,该方法将返回相同的字符串。

    类似的方法是这样的:

    Random random = new Random();
    public string Randomization(params string[] elements) {
          return elements[random.Next(elements.Length)];
    }
    

    对于您的情况,由于 params 关键字,用法将保持不变。

    string result = Randomization("a", "b");
    

    【讨论】:

      【解决方案4】:

      如果您必须在这两个值之间有 50% 的分布,即如果之前返回了 a,那么下次应该是 b,您可以考虑以下逻辑。

      我使用锁来支持线程安全。如果没有多线程要求,您可以删除它们。我使用了单例模式而不是静态变量。根据您的需要,您可以简化代码以使用静态变量而不是单例。

      第一个确定是通过检查对象创建的第二个是奇数还是偶数来完成的。

      using System;
      
      public class Program
      {
          public static void Main()
          {
              Console.WriteLine(Singleton.Instance.Randomization("one", "two"));
              Console.WriteLine(Singleton.Instance.Randomization("one", "two"));
              Console.WriteLine(Singleton.Instance.Randomization("one", "two"));
              Console.WriteLine(Singleton.Instance.Randomization("one", "two"));
              Console.WriteLine(Singleton.Instance.Randomization("one", "two"));
              Console.WriteLine(Singleton.Instance.Randomization("one", "two"));
          }
      }
      
      public sealed class Singleton
      {
          private static readonly Lazy<Singleton> lazy = new Lazy<Singleton>(() => new Singleton());
          public static Singleton Instance
          {
              get
              {
                  return lazy.Value;
              }
          }
      
          private static readonly object _lock = new Object();
          private bool _counter;
          private Singleton()
          {
              this._counter = DateTime.Now.Second % 2 == 0;
          }
      
          public string Randomization(string a, string b)
          {
              lock (_lock)
              {
                  _counter = !_counter;
                  return _counter ? a : b;
              }
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2015-06-18
        • 1970-01-01
        • 2012-05-17
        • 2020-02-28
        • 1970-01-01
        • 1970-01-01
        • 2013-05-05
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多