Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/233.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 使四舍五入值相加为所需产品_Php_Arrays - Fatal编程技术网

Php 使四舍五入值相加为所需产品

Php 使四舍五入值相加为所需产品,php,arrays,Php,Arrays,这是一个需要一些思考的编程问题,可以真正应用于任何编程语言 假设您有一个数组: $arr=array(10,7,4,4,3,2,1,1,1,1,1,1); 这个数组是动态的,可以是任何一组数字 还有一个乘数,比如说0.6 目标是一个接一个地显示每个数字,以使它们的相加尽可能接近总*乘数。在本例中,数字相加为36,*0.6表示21.6 这里有一个陷阱: 您必须对每个值进行四舍五入(仅限整数),因此您的真正目标是使数字相加尽可能接近22 不能使用任何函数来求数组的和。你只能循环一次 最基本的尝试是

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

假设您有一个数组:

$arr=array(10,7,4,4,3,2,1,1,1,1,1,1);
这个数组是动态的,可以是任何一组数字

还有一个乘数,比如说
0.6

目标是一个接一个地显示每个数字,以使它们的相加尽可能接近总*乘数。在本例中,数字相加为36,*0.6表示21.6

这里有一个陷阱:

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

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

    但是没有起作用……我想它越来越近了。

    我想我可以说服你两次循环

    $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] ++;
    }
    
    $arr=数组(10,7,4,4,3,2,1,1,1,1);
    $out=[];
    美元乘数=0.6;
    $sum=四舍五入(数组_sum($arr)*$multiplier);//这是一个循环!
    foreach($arr作为$value){
    $value=四舍五入($multiplier*$value);
    数组_push($out,$value);
    $sum-=$value;
    }
    而($sum>0){
    $sum--;
    $out[$sum]——;
    }
    而($sum<0){
    $sum++;
    $out[-$sum]++;
    }
    
    这里有一个单通方法:

    $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;
    
    $orig_sum=0;
    $rounded_sum=0;
    $new_arr=array();
    对于($i=0;$i

    计算
    $sum\u rounded
    $sum\u real
    在每个
    foreach
    循环迭代开始时的平均值。如果
    $sum\u round
    的平均值较大,请使用
    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;
    }
    

    你的问题是什么?错误在哪里?你在哪里卡住了?为什么不绕两圈呢?这是O(n),没什么大不了的。@YogeshSuthar我不知道最后的foreach循环应该怎么做,我想看看你们是否有什么想法。将数组中除了最后一个元素以外的所有元素乘以乘法器,然后四舍五入,然后相加。然后计算这个和预期的总和之间的差值,并用这个来替换最后一个元素。好主意,现在就尝试一下。取整$sum_的平均值总是更大,因为乘数小于一…@hellohellosharp:我更新了我的答案并添加了示例代码,请看看这是否适用于你。对于您的示例数据,
    $sum\u rounded
    应该只大两倍。太棒了!一个数组,一个循环,非常简单!我唯一需要添加的是在if语句中显示的实际$val。