很多场景算红包的要求:根本问题就是指定的钱,指定的个数,红包发完,钱不剩余,最小红包1分钱,最大也需要限制。

原理:割绳子算法:每次都取最大值为总绳长的随机值,最后将其排序,计算每两个的差值,总差值即就是总绳子长度,但是割绳子算法算出来的金额可能会出现超出最大金额的值,那么就会需要使用平均算法。
平均算法(自己取的名字):将超过最大限定金额的值全部重新赋值,并将他们舍去的部分,随机分给最小的金额,并保证最小的金额加上一个值不超过最大值即可。
洗牌算法:最终要将排序的金额进行打乱。

开源是程序员的基本美德

  1.        int pp = ;//元换算成分的比例
  2.  
  3. int total =(int)((decimal) * pp);//红包总额
  4. int num = ;//红包个数
  5. int min = (int)((decimal)0.02 * pp);//红包不少于
  6. int max = (int)((decimal) * pp);//最大红包不超过
  7.  
  8. if (min <= && min >= (total - max) / (num - ))
  9. {
  10. Console.WriteLine($"红包最小值异常:{total}分{num}个红包,最小值必须大于0,且不能小余{(total - max) / (num - 1)/100f}");
  11. return;
  12. }
  13. if (num * min > total)
  14. {
  15. Console.WriteLine($"红包最小值异常:{total}分{num}个红包,红包最小值不能超过{total / num / 100f}");
  16. return;
  17. }
  18. if (num * max < total)
  19. {
  20. Console.WriteLine($"红包最大值异常:{total}分{num}个红包,红包最大值不能小余{total / num / 100f}");
  21. return;
  22. }
  23. if (max > total - min * (num - ))
  24. {
  25. Console.WriteLine($"红包最大值异常:{total}分{num}个红包,红包最大值不能超过{(total - min * (num - 1)) / 100f}");
  26. return;
  27. }
  28.  
  29. float[] ret = new float[num];
  30. ret[] = ;
  31. int i = ;
  32. //下面不考虑随机数的唯一性,给每个人都预留最少的钱
  33. int totalByHundred = total - (num * min);
  34. Random random = new Random();
  35. while (i < num)
  36. {
  37. ret[i] = random.Next(totalByHundred);
  38. i++;
  39. }
  40. //先从大到小排序 将差值计算出来+最先预留的min值
  41. Array.Sort(ret);
  42. i = ;
  43. while (i < num - )
  44. {
  45. ret[i] = (ret[i + ] - ret[i] + min);//每个人都预留最少的钱
  46. i++;
  47. }
  48. ret[i] = (totalByHundred - ret[i] + min);//最后一个 仍然是最大可分值-自身+min值即可。
  49. //再次排序金额 将超出最大值的金额 全部重新赋值,并将差值累加给tempmax ,然后将tempmax再依次随机分给最小的金额
  50. Array.Sort(ret);
  51. float tempmax = ;
  52. for (int k = ret.Length - ; k >= ; k--)
  53. {
  54. if (ret[k] > max)
  55. {
  56. float t = random.Next(min,max);
  57. tempmax += ret[k] - t;
  58. ret[k] = t;
  59. }
  60. else
  61. {
  62. break;
  63. }
  64. }
  65. //分完为止 可能运气好 没有可分的
  66. while (tempmax > )
  67. {
  68. Console.WriteLine("触发平均算法执行");
  69. Array.Sort(ret);
  70. for (int k = ; k < ret.Length; k++)
  71. {
  72. //一轮分不完 将再次排序再分 tempmax为0即可
  73. if (tempmax > )
  74. {
  75. int tm = max - (int)ret[k];
  76. if (tempmax< tm)
  77. {
  78. //此处判断非常重要
  79. ret[k] = ret[k] + tempmax;
  80. tempmax = ;
  81. }
  82. else
  83. {
  84. float t = random.Next(tm);
  85. ret[k] = ret[k] + t;
  86. tempmax -= t;
  87. }
  88. }
  89. else
  90. {
  91. break;
  92. }
  93. }
  94. }
  95.  
  96. //最后利用洗牌算法进行打乱数组
  97. int currentIndex;
  98. float tempValue;
  99. for (int j = ; j < ret.Length; j++)
  100. {
  101. currentIndex = random.Next(, ret.Length - j);
  102. tempValue = ret[currentIndex];
  103. ret[currentIndex] = ret[ret.Length -- j];
  104. ret[ret.Length- - j] = tempValue;
  105. }
  106. //完美
  107. for (int j = ; j < ret.Length; j++)
  108. {
  109. Console.WriteLine($"第{j + 1}个红包:金额{(ret[j] / 100f)}元");
  110. }
  111. //最后检查总红包金额以及最大最小红包是否符合要求 肯定符合要求的 只是输出看一下
  112. Console.WriteLine($"红包总金额:{(ret.Sum() / 100f).ToString("F2")}元,红包最大值:{ret.Max() / 100f}元,红包最小值:{ret.Min() / 100f}元");

该算法由C#写成,更多交流请关注原文博客地址:

红包算法的一种

 

.NET C# 红包生成算法,可设置红包总额和数量,可限制最大最小红包的更多相关文章

  1. PHP用抛物线的模型实现微信红包生成算法的程序源码

    <?php /* *Author:Kermit *Time:2015-8-26 *Note:红包生成随机算法 */ header("Content-type:text/html;cha ...

  2. PHP微信红包生成算法的程序源码(用抛物线的模型实现)

    代码如下: <?php /* * 红包生成随机算法 */ header("Content-type:text/html;charset=utf-8"); date_defau ...

  3. php红包生成随机算法

    一.适用场景 红包总金额X,分配成Y个红包,每个红包随机金额. 二.生成算法 /** * 红包生成算法 * @param $money 总金额 * @param $number 红包数量 * @par ...

  4. 微信红包随机生成算法(PHP版)

    /** * 求一个数的平方 * @param $n */ function sqr($n){ return $n*$n; } /** * 生产min和max之间的随机数,但是概率不是平均的,从min到 ...

  5. java实现微信红包分配算法

    红包算法分析 有人认为,抢红包的额度是从0.01到剩余平均值*N(N是一个系数,决定最大的红包值)之间,比如一共发了10块钱,发了10个红包:第一个人可以拿到(0.01~1*N)之间的一个红包值,当然 ...

  6. 研究微信红包分配算法之Golang版

    今天来看一下红包的分配,参考几年前流传的微信红包分配算法,今天用Golang实现一版,并测试验证结果. 微信红包的随机算法是怎样实现的?https://www.zhihu.com/question/2 ...

  7. java使用BigDecimal 实现随机金额红包拆分算法

    原创代码,引用注明出处:https://www.cnblogs.com/guangxiang/p/12218714.html @Servicepublic class SplitRedPacketsS ...

  8. PHP微信红包的算法实现探讨

    header("Content-Type: text/html;charset=utf-8");//输出不乱码,你懂的 $total=10;//红包总额 $num=8;// 分成8 ...

  9. RocketMQ msgId生成算法

    当我们用RocketMQ发送信息的时候通常都会返回如下信息: SendResult [sendStatus=SEND_OK, msgId=0A42333A0DC818B4AAC246C290FD000 ...

随机推荐

  1. Vue6——v-model实现数据双向绑定

    博客地址 :https://www.cnblogs.com/sandraryan/ v-model 用于input标签,用于实现双向绑定,及时把数据的变化渲染在页面 双向绑定及原理 举个双向绑定的简单 ...

  2. 如何用JS和HTML 做一个桌面炒股小插件【原创】

    首先,使用node-webkit 做环境,废话不多说,直接贴HTML <!DOCTYPE html> <html xmlns="http://www.w3.org/1999 ...

  3. 将 vue.js 获取的 html 文本转化为纯文本

    我存入数据表中的数据是使用 html  格式,获取数据是使用 vue 获取. 遇到了一个问题,就是界面上显示的数据是 html 格式的,但是我需要它显示纯文本. 怎么做呢?首先在  js  中写一个将 ...

  4. LightOJ 1123 Trail Maintenance

    题意:n个城市m天.每一天修一条道路,输出当前天数的最小生成树,但是这里有一个条件,就是说最小生成树必须包括全部n个城市,否则输出-1 思路:边数有6000如果每一天跑一次最小生成树的话就接近O(m^ ...

  5. Python--day65--模板语言之变量相关语法

    Django的模板语言: 1.目前已经学过的模板语言: 2,模板语言总结: 常用语法 只需要记两种特殊符号: {{  }}和 {% %} 变量相关的用{{}},逻辑相关的用{%%}. 变量 在Djan ...

  6. hdu 2639 Bone Collector II(01背包 第K大价值)

    Bone Collector II Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others ...

  7. springboot整合mybatis完整示例, mapper注解方式和xml配置文件方式实现(我们要优雅地编程)

    一.注解方式 pom <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId& ...

  8. 关于 vue 生命周期 钩子函数 事件

    vue实例有一个完整的生命周期,也就是从开始创建.初始化数据.编译模板.挂载Dom.渲染->更新->渲染.卸载等一系列过程,我们称这是vue的生命周期. 通俗的将就是vue实例从创建到销毁 ...

  9. P1058 车厢重组

    题目描述 在一个旧式的火车站旁边有一座桥,其桥面可以绕河中心的桥墩水平旋转.一个车站的职工发现桥的长度最多能容纳两节车厢,如果将桥旋转 \(180\) 度,则可以把相邻两节车厢的位置交换,用这种方法可 ...

  10. Roslyn 使用 WriteLinesToFile 解决参数过长无法传入

    在写 Roslyn 的时候,经常需要辅助编译的工具,而这些工具需要传入一些参数,在项目很大的时候,会发现自己传入的参数比微软限制控制台可以传入的参数大很多,这时就无法传入了参数 本文告诉大家如何使用 ...