1

これはプログラミングに関する質問で、ある程度考える必要があり、どのプログラミング言語にも当てはまります。

次の配列があるとします。

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

この配列は動的で、任意の数値のセットにすることができます。

乗数もあります0.6

目標は、合計 * 乗数にできるだけ近くなるように、各数値を 1 つずつ表示することです。この場合、数値は 36 に加算され、*0.6 は 21.6 になります。

キャッチは次のとおりです。

  1. 各値 (整数のみ) を四捨五入する必要があるため、実際の目標は、数値の合計をできるだけ 22 に近づけることです。
  2. 関数を使用して配列の合計を解くことはできません。ループできるのは 1 回だけです。

最も基本的な試みは

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

しかし、うまくいきませんでした...でも、近づいていると思います。

4

3 に答える 3

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;

コードパッド

于 2013-03-28T05:54:18.620 に答える
0

ループの各反復の開始時$sum_roundedと両方の平均を計算します。の平均が大きい場合は、代わりに を使用します。$sum_realforeach$sum_roundedfloor()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;
}
于 2013-03-28T05:55:13.687 に答える
0

2回ループするように話しかけることができると思います。

$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] ++;
}
于 2013-03-28T05:45:50.160 に答える