【问题标题】:PHP: Can array of numbers add up to numberPHP:数字数组可以加起来吗
【发布时间】:2012-08-09 13:25:30
【问题描述】:

这更像是一个谜题。我实际上找到了一个解决方案,但它太慢了,我以为我失去了互联网连接(见下文)。

问题来了:

假设我有一个数字数组,如下所示:

$numbers_array = array(1, 2, 3, 4, 5, 6, 7, 8, 9);

假设我有一些数字,存储在变量中,如下所示:

$sum = 15;
$sum2 = 24;
$sum3 = 400;

我正在尝试创建一个函数,如果可以将 $numbers_array 中的任何数字相加(每个数字仅使用一次)以形成总和,则该函数将返回 true:

function is_summable($array_of_nums, $sum_to_check) {
    //What to put here?
}

var_dump(is_summable($numbers_array, $sum));
var_dump(is_summable($numbers_array, $sum2));
var_dump(is_summable($numbers_array, $sum3));

上面应该输出:

bool(true)
bool(true)
bool(false)

因为 7 + 8 = 15, 7 + 8 + 9 = 24,但 1-9 的组合不能创造 200。

这是我的极慢解决方案:

function is_summable($numbers, $sum) {
    //Sort provided numbers and assign numerical keys.
    asort($numbers);
    $numbers = array_values($numbers);

    //Var for additions and var for number of provided numbers.
    $total = 0;
    $numbers_length = count($numbers);

    //Empty var to fill below.
    $code = '';

    //Loop and add for() loops.
    for ($i = 0; $i < $numbers_length; $i++) {
        $code .= 'for ($n' . $i . ' = 0; $n' . $i . ' < ' . $numbers_length . '; $n' . $i . '++) {';

        if ($i != 0) {
            $code .= 'if ($n' . $i . ' != $n' . ($i - 1) . ') {';
        }

        $code .= '$total += intval($numbers[$n' . $i . ']);';
        $code .= 'if ($total == $sum) {';
        $code .= 'return true;';
        $code .= '}';
    }

    //Add ending bracket for for() loops above.
    for ($l = 0; $l < $numbers_length; $l++) {
        $code .= '$total -= intval($numbers[$n' . $i . ']);';
        if ($l != 0) {
            $code .= '}';
        }
        $code .= '}';
    }

    //Finally, eval the code.
    eval($code);

    //If "true" not returned above, return false.
    return false;
}

$num_arr = array(1,2,3,4,5,6,7,8,9);
var_dump(is_summable($num_arr, 24));

http://pastebin.com/1nawuwXK

一如既往,感谢您的帮助!

【问题讨论】:

  • 您正在尝试解决knapsack problem
  • 确实,这个问题会在Math 上找到更好的归宿。而且绝对不在 PHP 标记中...
  • @Jon 没听说过,但很有趣。
  • @DaveRandom 好的,我会在那里发布。我在 PHP 中使用该解决方案,因此我应用了该标签。再三考虑,这不是最合适的想法。
  • @apparatix:这是 CS 中最著名的问题之一。在这种情况下,您要解决“0-1 背包问题”,然后检查最优解是否精确 适合目标数字。最著名的方法是使用动态规划;维基百科有一个数学描述,但你会在互联网上找到很多额外的资源。

标签: php numbers sum add


【解决方案1】:

您的问题实际上是一个标准算法问题(正如 Jon 提到的背包问题),更具体地说是 Subset sum problem。它可以在多项式时间内解决(请查看wiki page)。

伪代码:

initialize a list S to contain one element 0.
for each i from 1 to N do
  let T be a list consisting of xi + y, for all y in S
  let U be the union of T and S
  sort U
  make S empty 
  let y be the smallest element of U 
  add y to S 
  for each element z of U in increasing order do
     //trim the list by eliminating numbers close to one another
     //and throw out elements greater than s
    if y + cs/N < z ≤ s, set y = z and add z to S 
if S contains a number between (1 − c)s and s, output yes, otherwise no

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-02-18
    • 2011-04-29
    • 2011-10-12
    • 1970-01-01
    • 2012-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多