我如何从这个数组中获得所需的总和

时间:2018-07-13 08:20:45

标签: php

这是我当前拥有的代码:

$required = 1.3;
$stacks = 0;
$remaining = $required;
$whichtakes = [];
$array_result = ['0.6', '0.5', '0.8', '0.7'];
for($i = 0; $i < count($array_result); $i++) {
    if($array_result[$i] <= $required  && $stacks + $array_result[$i]  <= $required) {
        $stacks += $array_result[$i];
        echo $remaining -= $array_result[$i];
        $whichtakes[] = $array_result[$i];
    }
}
print_r($whichtakes);

输出为

Array (
    [0] => 0.6
    [1] => 0.5
)

这仅获取0.6和0.5(前两个值)并给出一个剩余值(总和为1.1,因此剩余0.2)。但是输入有2个值,它们的总和与我的$required值匹配:0.8和0.7。

如何改善代码以找到这些值?如果没有精确匹配的值,我想得到一系列值,它们的总和尽可能接近,以使剩余值最小。

2 个答案:

答案 0 :(得分:0)

此算法将找到所有加起来为$required值的对:

$required = 1.3;
$array_result = ['0.6', '0.5', '0.8', '0.7'];

$answers = [];
foreach ($array_result as $value) {

    $remaining = $required - $value;
    if (in_array((string)$remaining, $array_result)) {
        $new_answer = ($value <= $remaining ? [$value, $remaining] : [$remaining, $value]);
        $answers[] = $new_answer;
    }
}

echo '<pre>';
print_r(array_unique($answers, SORT_REGULAR));
echo '</pre>';

输出:

Array
(
    [0] => Array
        (
            [0] => 0.6
            [1] => 0.7
        )

    [1] => Array
        (
            [0] => 0.5
            [1] => 0.8
        )

)

答案 1 :(得分:0)

经过评论中的更多解释后,您发现您想为此输入/输出找到一种算法:

输入:

  • 总金额和
  • 具有金额的数组

输出:

  • “最接近的子集”:从输入数组(不一定是一对)中选择的金额,其总和不大于给定的总金额。
  • 该子集的总和与给定总量之间的差

您可以实现以下目标:

生成所有组合,并以它们生成的总和(或余数)为键,但是当它们的总和太大时,停止添加元素。这可以通过对元素的简单迭代并更新哈希(通过将值加到先前找到的总和中而得到的总和(或余数)来确定)来完成。

这是它的外观:

// Input
$required = 1.3;
$array_result = [0.6, 0.5, 0.8, 0.7];

// Algorithm
$remainings = [(string)$required => []]; // Keyed by remaining value; gives array elements that have that remainder

foreach($array_result as $i => $val) {
    foreach($remainings as $remaining => $whichtakes) {
        if ($remaining >= $val) $remainings[(string)($remaining-$val)] = array_merge($whichtakes, [$val]);
    }
}
$remaining = min(array_keys($remainings));
$whichtakes = $remainings[(string)$remaining];

// Output
print_r($whichtakes);   // [0.6, 0.7]
print_r($remaining);    // 0