在微博上看到segmentfault上的一个题目,看了下问题,我自己想的就是先把每个人都分6元,然后在随机分配剩下的40元.看了下原题的答案,已经有这样的思路.哈哈.写下我的代码.
有两种做法:一种是从$leave里面随机 0 ~ ($max - $min)之间的数(可以是浮点数),然后随机用户的数组,抽取一个,判断两者相加是否大于$max,如果大于,跳过;小于的话就把相加的结果赋值给该用户.
另一种做法是先随机抽取一个用户,在根据用户对比$max的差值随机一个数,再相加给该用户.我用的是这种.
/**
* $n = 10; // 人数
* $money = 100; // 钱总和
* $min = 6; // 下限6
* $max = 12; // 上线 12;
*/
function sendHongbao($money=100, $n=10, $min=6, $max=12){
$arr = array_fill( 0, $n, $min); // 填充每个人的钱的数组
$leave = $money - $n * $min; // 还剩余多少钱
// 随机发放开始
while ($leave) {
// 随机用户
$lucky = array_rand($arr, 1);
if ($arr[$lucky] < $max){
// 判断随机数的上限
$randNum = mt_rand(1, ((($max - $arr[$lucky]) < $leave) ? ($max - $arr[$lucky]) : $leave ) );
$arr[$lucky] += $randNum;
$leave = $leave - $randNum;
}
}
return $arr;
}
理论上每个人的随机获取的钱是接近10的.所以测试方法是不是正确,先把代码跑100万次,看看每个人的结果是不是接近于10.
写个简单的测试代码如下:
$sum = array(0,0,0,0,0,0,0,0,0,0);
for($i=0; $i<1000000; $i++){
$res = sendHongbao();
$sum[0] += $res[0];
$sum[1] += $res[1];
$sum[2] += $res[2];
$sum[3] += $res[3];
$sum[4] += $res[4];
$sum[5] += $res[5];
$sum[6] += $res[6];
$sum[7] += $res[7];
$sum[8] += $res[8];
$sum[9] += $res[9];
}
echo "<pre>";
print_r($sum);
echo "</pre>";
结果如下:
Array
(
[0] => 9995735
[1] => 9998061
[2] => 9973085
[3] => 10001552
[4] => 9998657
[5] => 10002408
[6] => 9999013
[7] => 9998440
[8] => 10006077
[9] => 10026972
)
效率不高是个问题.如果有好的方法欢迎交流.