闲来无事,PHP撸两个红包算法

港控/mmm° 2022-05-26 04:26 256阅读 0赞

早上地铁里无聊,看到CSDN公众号推的一篇文章,是随机红包的实现,有兴趣的可以看原文,这里只做php版的代码实现

#

漫画:如何实现抢红包算法?

https://mp.weixin.qq.com/s/7yDbdKHJ3OmNw\_015Jc8Cg

废话不多说,上代码:

  1. class RedPackageService{
  2. private static $instance;
  3. private function __construct()
  4. {
  5. }
  6. private function __clone()
  7. {
  8. // TODO: Implement __clone() method.
  9. }
  10. public static function getInstance()
  11. {
  12. if(!(self::$instance instanceof self))
  13. self::$instance = new self;
  14. return self::$instance;
  15. }
  16. /**保证每个人拿到的概率相同(保证公平)
  17. * @param $total int 红包总金额,单位分
  18. * @param $number int 参与抢红包的数量
  19. * @return array
  20. * Array
  21. (
  22. [0] => 22.05 单位元,精确到分
  23. [1] => 9.15
  24. [2] => 27.35
  25. [3] => 12.84
  26. [4] => 25.74
  27. [5] => 0.94
  28. [6] => 26.93
  29. )
  30. */
  31. public function byAverage($total,$number)
  32. {
  33. $data = [];
  34. for($i=0;$i<$number;$i++)
  35. {
  36. if($number == ($i+1))
  37. $data[] = round($total/100,2);
  38. else {
  39. $area = round($total / ($number - $i), 0) * 2;
  40. $re = random_int(1, $area);
  41. $data[] = round($re/100,2);
  42. $total -= $re;
  43. }
  44. }
  45. return $data;
  46. }
  47. /**保证红包金额随机性
  48. * @param $total int 红包总金额 单位分
  49. * @param $number int 参与人数
  50. * @return array
  51. * Array
  52. (
  53. [0] => 3.49
  54. [1] => 7.83
  55. [2] => 27.24
  56. [3] => 4.53
  57. [4] => 15.31
  58. [5] => 32.61
  59. [6] => 33.99
  60. )
  61. */
  62. public function byRandom($total,$number)
  63. {
  64. $data = $divided_points = [];
  65. //获取随机分割点,在0-$total之间寻找$number-1个
  66. for($i=0;$i<$number-1;$i++)
  67. {
  68. $tmp_point = random_int(1,$total-1);
  69. //检查分割点是否存在
  70. while (in_array($tmp_point,$divided_points))
  71. {
  72. $tmp_point = random_int(1,$total-1);
  73. }
  74. array_push($divided_points,$tmp_point);
  75. }
  76. //加入终止分割点
  77. array_push($divided_points,$total);
  78. //分割点排序,从小到大,index会变动
  79. asort($divided_points);
  80. //根据分割点获取随机金额
  81. $a = 0;
  82. foreach ($divided_points as $b)
  83. {
  84. $data[] = round(($b-$a)/100,2);
  85. $a = $b;
  86. }
  87. // for($i=1;$i<$number;$i++)
  88. // $data[] = round(($divided_points[$i]-$divided_points[$i-1])/100,2);
  89. return $data;
  90. }
  91. }

测试执行代码

  1. $re = RedPackageService::getInstance()->byRandom(12500,7);
  2. print_r($re);

可能需要注意一下你的namespace

两个方法各有所长各有缩短,大家理性看待,随便玩玩,开心就好

发表评论

表情:
评论列表 (有 0 条评论,256人围观)

还没有评论,来说两句吧...

相关阅读