-2

たとえば、1、2、5、10、20、50 の額面セットで 237 の値を取得するには、値を構成する最適な方法は 4x50 + 1x20 + 1x10 + 1x5 + 1x2 になります。しかし、PHPでプログラム的にそれを達成する方法は?

4

1 に答える 1

1

次のようなことができます:

$number = 237;

$values = array(1, 2, 5, 10, 20, 50);
arsort($values); // greater to lower sorting
$numberOf = array();

foreach ($values as $v) {
    $numberOf[$v] = floor($number / $v);
    $number -= $numberOf[$v] * $v;
}

var_dump($numberOf);

これにより、次のものが生成されます。

array(6) {
  [50]=>
  int(4)
  [20]=>
  int(1)
  [10]=>
  int(1)
  [5]=>
  int(1)
  [2]=>
  int(1)
  [1]=>
  int(0)
}

デモ

編集:有限額の金種

無限の宗派がない場合は、これを試すことができます:

$number = 237;

$values = array(1, 2, 5, 10, 20, 50);
$quantities = array(7, 1, 3, 5, 2, 3);
// sort by greater value to lower value
// but keeping the related quantities
array_multisort($values, SORT_DESC, $quantities);

$numberOf = array();

foreach ($values as $i => $v) {
    $quantity = $quantities[$i]; // get the corresponding quantity
    // if we have less than the required value, we put the max we can
    $numberOf[$v] = floor($number / $v) > $quantity ? $quantity : floor($number / $v);
    $number -= $numberOf[$v] * $v;
}

var_dump($numberOf);

3この例では、の数量しかありません50。したがって、次のような出力が得られます。

array(6) {
  [50]=>
  int(3)
  [20]=>
  int(2)
  [10]=>
  float(4)
  [5]=>
  float(1)
  [2]=>
  float(1)
  [1]=>
  float(0)
}

3 * 50 + 2 * 20 + 4 * 10 + 5 * 1 + 2 * 1 + 1 * 0 = 237

ヤッピー!
デモ

この重要な行を理解するには、 array_multisort()も参照してください。

array_multisort($values, SORT_DESC, $quantities);

さらに良いことに、すぐに使える機能があります:

function getDenominations($amount, $denominations, $quantities = null) {
    if (is_array($quantities) && count($denominations) != count($quantities)) return false;
    array_multisort($denominations, SORT_DESC, $quantities);

    $numberOf = array();

    foreach ($denominations as $i => $v) {
        $quantity = $quantities[$i]; 
        $numberOf[$v] = floor($amount/ $v) > $quantity ? $quantity : floor($amount / $v);
        $amount -= $numberOf[$v] * $v;
    }

    return $amount == 0 ? $numberOf : false;
}

このように使用するには:

$result = getDenominations(
    237,
    array(1, 2, 5, 10, 20, 50),
    array(7, 1, 3, 5, 0, 4)
);

var_dump($result);

戻り値: 配列 | ブール値

数量が指定されていない場合は、無制限の額面単位で返されます。指定されている場合、有限の量で。
十分な量がない場合、または配列のサイズが異なる場合は、「false」を返します。

于 2013-08-29T14:40:20.757 に答える