PHP将变量除以多个多维数组以不产生余数

时间:2014-10-14 20:13:24

标签: php math multidimensional-array

我所拥有的项目是游戏中材料的报销。这些材料有下面列出的各种封装。我的部分代码给了我需要报销的单位总数,我必须使用"包"来自下面的数组。

这是多维数组。 $ item [' ore'] [100]数组表示列出的项目在使用时会产生100个单位,而堆叠只能为100(key => stacksize)。同样,对于$ item [' ore'] [500]在使用时会产生500个单位,并且只能叠加到100个单位:

$item = array(
 'ore'  =>  array(
    100 => array(
        'name'  => "Item 1",
        'stacksize' => 100,
    ),
    500 => array(
        'name'  =>  "Item 2",
        'stacksize' => 100,
    ),
    1000    =>  array(
        'name'  => "Item 3",
        'stacksize' => 100,
    ),
),

因此,1x项目1给出100个单位,1x项目2给出500个单位,1x项目3给出1000个单位。我的部分代码中的$ totalOre变量指示我有15,825个单位来报销总数(作为示例)。显然我会有一些额外的报销,因为我没有一个小于100个单位的项目(如果用户在这种情况下获得更多的话,这不是什么大问题)。

所以我需要一个代码片段来告诉我需要报销15x项目3,1x项目2和4x项目1共计15,900个单位。

另外,如果我说.... $ totalOre = 219,427,我需要我的代码来指示我发送100x项目3,然后是100x项目3,然后是19x项目3,然后是1x项目2,共计219,500单位,因为' stacksize'限制为100(我不能向用户发送超过100x的这些项目,否则他们无法获得这些项目。)

我假设除了Modulus(%)运算符之外还需要某种循环。我试过了

$reimburseOre = 0;
$reimburseOre = $reimburseOre % $items['ore'][1000];

并提出0.您可以提供的任何帮助都会非常感激,即使只是朝着正确的方向前进。

谢谢。

编辑:尝试添加数量'数量'我的数组的键(设置为1000),然后是以下代码片段,结果是-523(根本不正确):

    $oreReimbursement = 0;
    if ($totalOre % $items['ore'][1000]['Qty'] != 0) {
        $oreReimbursement -= $totalOre % $items['ore'][1000]['Qty'];
    }
    echo $oreReimbursement; ?>

2 个答案:

答案 0 :(得分:1)

这里有一些代码可以让你上路。你必须解决这些问题,但这应该有助于了解你必须偿还的矿石组合。

# $target is the amount of ore to be repaid
$target = 481726;

# first, reverse sort the keys of 'ore' so they're in descending numerical order
krsort( $item['ore'] );
# initialise an array to contain our "order" of ore.
$order = [];

# for every value of ore, starting with the largest amount
foreach ( $item['ore'] as $a => $v ) {
    # if the target to be reached is larger than the amount, $a
    if ($target > $a) {
        # floor( $target / $a ) means round down $target/$a to the nearest integer
        # add the name (Item x) and the rounded down number to the order.
        $order[ $v["name"] ] = floor($target / $a);
        # reset $target to the remainder
        $target = $target % $a;
    }
}

# if we still have some ore left to give, add one lot of the smallest ore quantity
if ($target) {
    ( isset($order[ $v["name"] ]) )
    ? $order[ $v["name"] ]++
    : $order[ $v["name"] ] = 1;
}

print_r($order);

481726的输出:

Array
(
    [Item 3] => 481
    [Item 2] => 1
    [Item 1] => 3
)

你应该能够弄清楚如何将485堆栈分成100组。

答案 1 :(得分:1)

$totalOre = 15825;
$totalWood = 219427;

reimburse($item['ore'], $totalOre);
reimburse($item['wood'], $totalWood);

function reimburse($units, $total) {
$unitSizes = array_keys($units);
rsort($unitSizes); // order from high to low
$temp = $total;
$actual = array();
$reimbursed = 0;
foreach($unitSizes AS $unitSize) {
  $stacks = floor($temp / $unitSize);
  $stacksize = $units[$unitSize]['stacksize'];
  $itemName = $units[$unitSize]['name'];
  while($stacks > $stacksize) {
    $actual[$itemName] += $stacksize;
    $reimbursed += $stacksize * $unitSize;
    $stacks -= $stacksize;
    $temp -= $stacksize * $unitSize;
  }
  if ($stacks > 0) {
    $actual[$itemName] += $stacks;
    $reimbursed += $stacks * $unitSize;
    $temp -= $stacks * $unitSize;
    $stacks = 0;
  }
}
if ($temp > 0) {
  $actual[$itemName]++;
  $reimbursed += $unitSize;
}
print 'Total: ' . $reimbursed . ' (' . $total . ')' . "\r\n";
print_r($actual);
}

输出:

Total: 15900 (15825)
Array
(
    [Item 3] => 15
    [Item 2] => 1
    [Item 1] => 4
)
Total: 219500 (219427)
Array
(
    [Item 6] => 219
    [Item 4] => 5
)

请参阅demo

正如你所看到的,它有一个缺陷:在木材例子中它不是5倍项目4,它应该是一个项目5.为了解决这个问题,需要首先确定最终的总报销。

sort($unitSizes); // order from low to high to get lowest unitsize
$smallestUnit = $unitSizes[0];
$total = ceil($total / $smallestUnit) * $smallestUnit;

请参阅demo