2013-03-28 19 views
1

这是一个编程问题,需要一些思考,并且可以真正应用于任何编程语言。将四舍五入的值累加到所需的产品上

假设你有数组:

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

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

你也有一个乘数,可以说0.6

目标是逐一显示每个数字,以尽可能接近总乘数乘数的方式显示。在这种情况下,该号码添加到36,* 0.6为您提供了21.6

这里的渔获:

  1. 你必须圆每一个值(仅整数),让你真正的目标是使数字尽可能接近22。
  2. 您不能使用任何函数来求解数组的总和。你只能循环一次。

最基本的企图都将是

$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); 
} 

但没有工作...我认为这是虽然越来越接近。

+0

你的问题是?错误在哪里?你卡在哪里? – 2013-03-28 05:39:14

+0

为什么不循环两次?这是O(n),没什么大不了的。 – 2013-03-28 05:39:35

+1

@YogeshSuthar我不确定从最后的foreach循环到哪里,并想看看你们是否有任何想法。 – hellohellosharp 2013-03-28 05:44:27

回答

0

foreach循环的每次迭代的开始计算平均两个$sum_rounded$sum_real。如果$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; 
} 
+0

不错的想法,现在就试试这个。 – hellohellosharp 2013-03-28 05:58:34

+0

$ sum_round的平均值总是较大,因为乘数小于1 ... – hellohellosharp 2013-03-28 06:06:30

+0

@hellohellosharp:我更新了我的答案并添加了示例代码,请看看它是否适合您。用你的示例数据'$ sum_rounded'应该只有两倍。 – Kaivosukeltaja 2013-03-28 06:29:55

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] ++; 
} 
0

这里的一个1通法:

$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