将10000块钱分成5份,且每一份之间的相差的值$d不一样,并且相差$d得大于100。
2 回答
![?](http://img1.sycdn.imooc.com/545868cd00013bbb02200220-100-100.jpg)
手掌心
TA贡献1942条经验 获得超3个赞
谢邀!
- 对随机的五位数排序,最小在前最大在后的依次增大
- 前4次是随机值
- 第5次是总数减去前四次随机值
- 重要的就是前四次随机值的范围,就是其中的最小值和最大值。这时候如果最小值和最大值限制越多到后面越容易产生随机值,并且要保证最小值要大于前一个随机值的100以上。而关于最大值就简单多了,尽可能小,但是不会比最小值小。并且不会比我下面例子中使用的最大值( $rand_max )大。(至于为什么你可以思考下)
- 如果产生的随机值中差值产生重复,那么就重新产生随机值
<?php
$sum = 10000;
$diff = 100;
$count = 5;
$return = array();
$min = 0;
$i = 1;
while($i < $count) {
// 随机数不符合要求时的结果初始化
if(isset($return[$i]) || isset($return[$i+1])) {
unset($return[$i]);
unset($return[$i+1]);
}
// 剩余数
$remain_sum = $sum - array_sum($return);
// 剩余需要随机的个数
$remain_count = intval($count - count($return));
// 高斯求最小差值和,分两部分:S = n(n+1)(2n+4)/12 + $diff * ((n-1)(n-2)/2)
$min_diff = $remain_count * ($remain_count - 1) * (2 * ($remain_count - 1) + 4) / 12 + ($remain_count * ($remain_count - 1) / 2) * $diff;
// 随机范围的最小值
$min = $i == 1 ? 1 : $return[$i-1] + $diff + 1;
// 在范围内获取随机数
mt_srand((double)microtime() * 1000000);
// 随机范围的最大值
$rand_max = intval(($remain_sum - $min_diff) / $remain_count);
// 产生随机数
$min = mt_rand($min, $rand_max);
// 放入返回的数组
$return[$i] = $min;
if($i == $count - 1) {
// 最后一个随机数直接取总数减去前面的随机数
$return[$i+1] = $remain_sum - $min;
}
if(check_diff($return) === false) {
$i--;
continue;
}
$i++;
}
var_dump($return);die;
// 判断数组内是否有差值相等
function check_diff($arr) {
if(empty($arr)) {
return false;
}
$arr = array_map('intval', $arr);
sort($arr);
$count = count($arr);
$diff_arr = array();
for($i = $count - 1; $i >= 0; $i --) {
for ($j = 0; $j < $count; $j ++) {
if($arr[$i] <= $arr[$j]) {
continue 2;
}
$diff_arr[] = $arr[$i] - $arr[$j];
}
}
if(count($diff_arr) === count(array_unique($diff_arr))) {
return true;
}
return false;
}
![?](http://img1.sycdn.imooc.com/5458683f00017bab02200220-100-100.jpg)
慕少森
TA贡献2019条经验 获得超9个赞
function splitMoney($money,$num,$difference){
$arr = array();
$v = $money / $num;
for($i = 0;$i < $num - 1; $i ++){
$cur = mt_rand($difference , $difference + ($difference/2));
if($arr[$i] == 0){
$arr[$i] = $v - ($cur/2);
$arr[$i + 1] = $v + ($cur/2);
}else{
$arr[$i + 1] = $v + $cur;
}
}
return $arr;
}
伪代码如上,另外你需要处理总和不等于实际金额的问题。
- 2 回答
- 0 关注
- 338 浏览
添加回答
举报
0/150
提交
取消