春节在家无聊,抢红包的时候想起来,不如自己写一个微信抢红包算法来练练手。本以为是非常简单的一个事情,但真正写下来也算是一波三折,不禁感叹,在程序员的路上,我还是太嫩了啊!写这篇文章的原因也是想与广大网友集思广益,获得更好的学习。
基本思路
基本思路很简单,用户可以输入红包个数和红包总金额,然后点击生成按钮,就能生成一组随机数。效果图如下:
Paste_Image.png图方便,引入vue的数据绑定,代码如下:
<div id="wrapper">
随机数个数<input type="text" v-model='num'><br>
随机数之和<input type="text" v-model='sum'><br>
<button v-on:click='getRandom'>生成随机数</button>
<ul>
<li v-for='item in list'>
{{item}}
</li>
</ul>
</div>
<script src='node_modules/vue/dist/vue.min.js'></script>
var vi=new Vue({
el:'#wrapper',
data:{
num:0,
sum:0,
list:[],
},
methods:{
getRandom:function(){
var app=this
var isOk=false
while(!isOk){
for (var i = app.num-1,sum_2=0,exist=0,list=[]; i >= 0; i--) {
list[i]=parseFloat((Math.random()*(parseFloat(app.sum)-exist)).toFixed(2))
sum_2+=list[i]
exist+=list[i]
}
console.log(list)
if (sum_2==parseFloat(app.sum)) {
isOk=true
app.list=list
}
}
},
},
})
代码逻辑并不复杂,相信大家能够看得懂,就不多做解释了。我更想提的是一个bug,生成随机数后,会出现分布不均匀的现象。
下面附上5次随机生成结果:
相信大家发现了,前面生成的数会很大,后面生成的数会非常小,但检查代码并没有逻辑错误。如果广大网友如果有所想法,请在评论区留言,不胜感激!
网友评论
首先额度最小应该是0.01,随机数小于0.01就取值0.01。最大应该是:剩余红包的总金额的平均数的两倍。就是红包每被抢一次,就重新生成一次红包对应额度。比如发100块钱5个随机红包。前面被抢了2个,假设剩余红包40块,那剩下三个红包应该在0.01到26.67之间,以此类推,直到抢完。
微信那个应该还用到正态分布之类的知识吧,其实可以自己多次试验,画画图,自己验证一下。