关于若干数据平均放入若干个盒子的问题
前段时间面试碰到的一个很有趣的问题:
有若干条数据,将这些数据平均放入若干个盒子中,盒子的个数有可能新加,有可能减少,20分钟内用代码实现
:stuck_out_tongue_closed_eyes:
回来后偶尔想起这个问题,不解决心里总是不舒服的,在网上找了一番之后,不知道是不是打开姿势不对,没有找到自己想要的,于是只好自己动手了,花了一点时间想思路,又花了大概半天的时间将思路实现
仅仅只是实现了功能,下面上代码:
<?php
$a = ['1','2','3','4','5','6','7','8','9','10','11','12','13'];
$b = [
'a'=>['a1','a2','a3'],
'b'=>['b1','b2','b3','b4','b5'],
'c'=>['c1','c2'],
'd'=>[],
'e'=>[],
'f'=>['f1'],
];
// 获取每个盒子里已经放进去的个数
$d = [];
foreach ($b as $k=>$v){
$d[$k] = count($v);
}
// 获取所有盒子已经放进去的总的个数
$e = array_sum($d);
// 获取需要放的和已经放进去的总和
$f = bcadd(count($a),$e);
// 获取平均每个盒子需要放进去的个数 = 盒子的个数/总个数
$num = floor(bcdiv($f,count($b)));
// 获取多出来的个数
$remainder = fmod($f,count($b));
// 获取每个盒子剩余需要放进去的个数
$g = [];
foreach ($d as $e_k=>$e_v){
$g[$e_k]['name'] = $e_k;
$new_num = bcsub($num,$e_v);
$g[$e_k]['num'] = $new_num;
}
// 如果不能整除,将多余的依次分给各个盒子,直到分完为止
$new_g = array_values($g);
//print_r($new_g);die;
// 求出每个盒子真正应该放的个数
$h = [];
$y = 0;
foreach ($new_g as $g_k=>$g_v){
// 存放多余数据的时候,先检查当前盒子内是否满足存放条件(已有个数+1是否大于平均每个盒子需要放进去的个数)
$has_num = $d[$g_v['name']] ?? 0; // 已经在盒子里面的个数
// 如果需要放进多余数据,检查当前已有个数+1后是否等于总的平均个数+1(每个盒子分完后多出来的数据才是剩余的数据)
if(bcadd($has_num,1) > bcadd($num,1)){
$h[$g_v['name']] = ($g_v['num'] < 0) ? 0 : $g_v['num'];
continue;
}
if(bcadd($y,1) <= $remainder){
$h[$g_v['name']] = bcadd($g_v['num'],1);
}else{
$h[$g_v['name']] = $g_v['num'];
}
$y++;
}
$j = get_result_arr($a,$h);
function get_result_arr($arr,$result){
$i = 0;
$arrT = [];
foreach ($result as $r_k=>$r_v){
$arrT[$r_k] = array_slice($arr, $i ,$r_v);
$i = bcadd($i,$r_v);
}
return $arrT;
}
$m = [];
$merge_arr = [];
foreach ($b as $b_k=>$b_v){
if(isset($j[$b_k])){
$merge_arr = $j[$b_k];
}
$m[$b_k] = array_merge($b_v,$merge_arr);
}
print_r($m);die;
最后的结果大概是这样
有兴趣的大佬欢迎研究一下,看看有没有更简单的方法
()
本作品采用《CC 协议》,转载必须注明作者和本文链接
不错不错 学习学习
配图纯属秀操作...

@青石 感谢大佬花时间研究:kissing_heart:
用我上次分享的随机序列生成算法就行了: 假设m条数据,n个盒子,先生成一个随机序列arr,第一个盒子放arr的前floor(m/n)条数据,依此类推,最后一个盒子放最后m%n条数据
@生活无限好 可能大佬根本没花时间:smile: