2013-03-28 22 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