zoukankan      html  css  js  c++  java
  • 再来写一个随机数解决方案,对Random再来一次封装

    本文提供对Random的封装,简化并扩展了其功能

    • 获取随机数,确保同时调用不会重复
       //new Random().Next(5);
       RandomTask.Next(5);
    • 从一个列表中,随机获取其中某个值
                  List<string> lsTest = new List<string>
                  {
                      "1","2","3","4","5"
                  };
                  string randomValue = RandomTask.PickOne(lsTest);
                  Console.WriteLine(randomValue);
    • 从一个列表中,随机获取其中多个值
      List<string> someRandomValue = RandomTask.PickAny(lsTest, 3);
      Console.WriteLine(string.Join(",", someRandomValue));
    • 想按某个概率返回bool值,可以这么写
                  bool is30Per = RandomTask.PickBoolByProp(0.3);
                  Console.WriteLine(is30Per);
    • 最复杂的,一个list中有a,b两个数据,a按照70%概率返回而b按30%返回,就这样写
                  Dictionary<string, double> lsTestAB = new Dictionary<string, double>
                  {
                      {"A",0.7 },
                      { "B",0.3}
                  };
                  string aOrb = RandomTask.PickOneByProb(lsTestAB);
                  Console.WriteLine(aOrb);
    • 源码
          public static class RandomTask
          {
              private static readonly Random _random = new Random();
      
              public static int Next()
              {
                  lock (_random)
                  {
                      return _random.Next();
                  }
              }
      
              public static int Next(int max)
              {
                  lock (_random)
                  {
                      return _random.Next(max);
                  }
              }
      
              public static int Next(int min, int max)
              {
                  lock (_random)
                  {
                      return _random.Next(min, max);
                  }
              }
      
              /// <summary>
              /// 按概率获取
              /// </summary>
              /// <param name="trueProp"></param>
              /// <returns></returns>
              public static bool PickBoolByProp(double trueProp = 1)
              {
                  if (trueProp > 1)
                  {
                      trueProp = 1;
                  }
                  if (trueProp < 0)
                  {
                      trueProp = 0;
                  }
                  Dictionary<bool, double> wt = new Dictionary<bool, double>
                  {
                     { true , trueProp },
                     { false , 1 - trueProp }
                  };
                  return wt.PickOneByProb();
              }
      
              /// <summary>
              /// 按指定概率获取随机结果
              /// </summary>
              /// <param name="sourceDic">a 0.8 b 0.1 c 0.1</param>
              /// <returns>随机结果 [a,b,c]</returns>
              public static T PickOneByProb<T>(this Dictionary<T, double> sourceDic)
              {
                  if (sourceDic == null || !sourceDic.Any())
                  {
                      return default(T);
                  }
      
                  int seed = (int)(10 / (sourceDic.Values.Where(c => c > 0).Min()));
                  int maxValue = sourceDic.Values.Aggregate(0, (current, d) => current + (int)(seed * d));
      
                  int rNum = Next(maxValue);
                  int tem = 0;
                  foreach (KeyValuePair<T, double> item in sourceDic)
                  {
                      tem += (int)(item.Value * seed);
                      if (tem > rNum)
                      {
                          return item.Key;
                      }
                  }
                  return default(T);
              }
      
              /// <summary>
              /// 随机从List中获取一项
              /// </summary>
              /// <typeparam name="T"></typeparam>
              /// <param name="source"></param>
              /// <returns></returns>
              public static T PickOne<T>(this List<T> source)
              {
                  if (source == null || !source.Any())
                  {
                      return default(T);
                  }
                  return source[Next(source.Count)];
              }
      
              /// <summary>
              /// 
              /// </summary>
              /// <typeparam name="T"></typeparam>
              /// <param name="source"></param>
              /// <param name="c"></param>
              /// <returns></returns>
              public static List<T> PickAny<T>(this List<T> source, int c)
              {
                  if (source == null || !source.Any())
                  {
                      return default(List<T>);
                  }
                  if (source.Count <= c)
                  {
                      return source;
                  }
                  List<T> ls = new List<T>();
                  for (int i = 0; i < c; i++)
                  {
                      var t = source.PickOne();
                      if (!ls.Contains(t))
                      {
                          ls.Add(t);
                      }
                  }
                  return ls;
              }
          }
    • 大家试试吧,真的挺好用的
  • 相关阅读:
    金山快盘的登录提醒
    排列到随机, 到随机选择,对于植物模拟世界 混沌
    转载 多层影藏 和显示
    庆生写的东西
    布料修改器的用法。
    像素相关
    模拟c++ 控件
    侧his
    输出文件
    win7 xp 删除一些 顽固的自动项目
  • 原文地址:https://www.cnblogs.com/SmallZL/p/7003095.html
Copyright © 2011-2022 走看看