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

PHP将一个变量除以多个多维数组以不产生余数,php,math,multidimensional-array,Php,Math,Multidimensional Array,我的项目是在一个游戏的材料偿还。这些材料有以下列表中列出的各种包装。我的部分代码给出了我需要偿还的单位总数,我必须使用下面数组中的“包” 这是多维数组。$item['ore'][100]数组表示列出的项在使用时提供100个单位,并且仅堆叠到100(key=>stacksize)。同样,对于$item['ore'][500]而言,使用时可提供500个单位,并且仅堆叠到100: $item = array( 'ore' => array( 100 => 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,
    ),
),
因此,1个项目1给出100个单位,1个项目2给出500个单位,1个项目3给出1000个单位。我的代码中的$totalOre变量指示我有15825个单位要偿还总额(例如)。显然,我会有一些额外的,将得到补偿,因为我没有一个项目,提供小于100个单位(不是一个大问题,如果用户在这种情况下得到多一点)

所以我需要一个代码片段来告诉我,我需要偿还15倍的第3项、1倍的第2项和4倍的第1项,总共15900个单位

此外,如果我说……$totalOre=219427,我需要我的代码来指示我发送100x项目3,然后发送100x项目3,然后发送19x项目3,然后发送1x项目2,总共发送219500个单位,因为“stacksize”限制为100(我不能向用户发送超过100x的这些项目,否则他们将无法获得)

我假设除了模(%)操作符之外,还需要某种循环。我试过了

$reimburseOre = 0;
$reimburseOre = $reimburseOre % $items['ore'][1000];
结果是0。如果您能提供任何帮助,我们将不胜感激,哪怕只是向正确方向伸出一只手

多谢各位

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


这里有一些代码可以帮你上路。你必须计算出矿堆,但这将有助于了解你必须偿还的矿石组合

# $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组

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

如您所见,它有一个缺陷:在wood示例中,它应该是一个项目5,而不是项目4的5倍。要解决这个问题,首先需要确定最终的报销总额

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

请参阅。

您为什么要凑齐?对于给定的矿石数量,您是否试图获得许多最昂贵的物品?您是否尝试过编写一些代码?你能展示一下你拥有的东西并解释为什么它不起作用吗?我必须汇总-否则我们会短缺用户材料,因为我们没有价值低于100个单位的包装(如果你需要58个以上的单位,我们汇总并在100个包装中给用户额外的42个,这不是什么大问题)。我把我已经尝试过的东西放在我的问题中-我没有任何其他的例子,因为我几乎被这个问题难住了。不需要对木材单元重复相同的代码——只需重构“ore”代码,使其适用于
$item
数组中的任何资源。你是对的,我最初试图做一些不同的事情。更新的答案和演示。这是一个非常好的开始和快速的代码。谢谢你的帮助!
sort($unitSizes); // order from low to high to get lowest unitsize
$smallestUnit = $unitSizes[0];
$total = ceil($total / $smallestUnit) * $smallestUnit;