使舍入值合计为所需产品

时间:2013-03-28 05:36:09

标签: php arrays

这是一个需要思考的编程问题,并且可以真正应用于任何编程语言。

假设你有数组:

$arr=array(10,7,4,4,3,2,1,1,1,1,1,1);

这个数组是动态的,可以是任何数字集。

你也有一个乘数,比方说0.6

目标是逐个显示每个数字,使它们尽可能接近总*乘数。在这种情况下,数字加到36,* 0.6给你21.6

这是捕获:

  1. 您必须对每个值进行舍入(仅限整数),因此您的真正目标是使数字尽可能接近22。
  2. 您不能使用任何函数来求解数组的总和。你只能循环一次。
  3. 最基本的尝试是

    $multiplier = 0.6;
    $sum=0;
    foreach($arr AS $value){
    $sum+=round($multiplier * $value);
    }
    

    但这不起作用,因为1 * 0.6总是会循环到1。

    我认为这可能是这样的:

    $multiplier = 0.6;
    $sum=0;
    foreach($arr AS $value){
    $real=$multiplier * $value;
    $rounded=round($multiplier * $value);
    $sum_rounded += $rounded;
    $sum_real += $real;
    //Somehow compare the two sums and break the foreach 
    }
    

    我不知道从哪里开始。你们觉得怎么样?

    试过这个:

    $sum_real=0;
    $sum_round=0;
    $count=0;
    
    foreach($rows AS $arr){
        $count+=1;
        $real_val=$arr*$multiplier;
    
        $sum_round+=round($real_val);
        $sum_real+=$real_val;
        $avg_round=$sum_round/$count;
        $avg_real = $sum_real/$count;
    
        $val = ($avg_round>$avg_real) ? floor($real_val) : round($real_val);
    }
    

    但是没有奏效......我认为它已经接近了。

3 个答案:

答案 0 :(得分:0)

我想我可以跟你说两次循环。

$arr = array(10,7,4,4,3,2,1,1,1,1,1,1);
$out = [];
$multiplier = 0.6;

$sum = round(array_sum($arr) * $multiplier); // that's a loop!

foreach ($arr as $value) {
    $value = round($multiplier * $value);
    array_push($out, $value);
    $sum -= $value;
}

while ($sum > 0) {
    $sum --;
    $out[$sum] --;
}

while ($sum < 0) {
    $sum ++;
    $out[-$sum] ++;
}

答案 1 :(得分:0)

这是一次通过法:

$orig_sum = 0;
$rounded_sum = 0;
$new_arr = array();
for ($i = 0; $i < count($arr)-1; $i++) {
  $orig_sum += $arr[$i];
  $new_elt = round($arr[$i] * $multiplier);
  $rounded_sum += $new_elt;
  $new_arr[] = $new_elt;
}
$orig_sum += $arr[$i];
$expected_rounded_sum = round($orig_sum * $multiplier);
$new_arr[] = $expected_rounded_sum - $rounded_sum;

CODEPAD

答案 2 :(得分:0)

计算$sum_rounded循环每次迭代开始时$sum_realforeach的平均值。如果$sum_rounded的平均值较大,请使用floor()代替round()

编辑:您实际上根本不需要计算平均值,因为数字将被相同的数字除以且不会影响哪一个更大。另外,将要增加的$value添加到比较中。

foreach($arr AS $value){
  $real=$multiplier * $value;
  $rounded=round($multiplier * $value);
  if($sum_rounded + $rounded > $sum_real + $real) {
    $sum_rounded += floor($multiplier * $value);
  }
  else {
    $sum_rounded += $rounded;
  }
  $sum_real += $real;
}