【问题标题】:PHP Function or Algorithm to find what elements in an array add up exactly to a certain numberPHP函数或算法查找数组中的哪些元素加起来正好等于某个数字
【发布时间】:2013-08-06 09:54:30
【问题描述】:

您好,我正在寻找一种算法或函数来查找数组中的哪些元素组加起来达到某个数字。可能不止一个,所以我希望返回数组中从左到右读取的第一个好的组。

例如,假设我有一个随机数数组... $x = array(500, 90, 50, 200, 10, 300, 900) 我希望识别任何一组数组元素加起来给定数字 X,比如 1,000。

在这种情况下,数组 $x 的元素 0,3,5 是第一个加起来为 1,000 (500 + 200 + 300) 的元素。元素 1,4,6 也加起来 1,000 (90 + 10 + 900) 但不是第一个,所以我们可以忽略它们。 该函数应返回具有正确索引位置的新数组 $y = array(0,3,5)。

任何帮助表示赞赏!谢谢:-)

【问题讨论】:

  • 这称为subset sum problem,通常无法在合理的时间内解决。当然对于这么小的输入,你可以暴力破解它。
  • 问题是人类可以智能地解决这个问题,即使你可以让算法像人类一样思考这样的计算,但程序不会放弃人类很快就会意识到的地方没有正确的组合。换句话说,当你有一组没有解的数字时,程序所做的任何尝试都将是暴力破解。
  • 有最大值吗?例如 1 到 4 个数字,或任何大于 1 的元素集合?另外,如果目标是 10,你会得到 10 的匹配,还是没有结果?
  • @Flosculus:“人类很快就会意识到没有正确的组合”=> 人类会错的。您可以在脑海中解决这个问题的案例非常简单,以至于您的手机可以在您阅读数字的时间内解决一千次。
  • @Flosculus:当然,如果您希望他们(random example),他们可以停下来想“这太花时间了”。无论如何,这与最初的“人类将意识到没有正确的组合”完全不同——人类在这类工作中实际上是无用的。更准确的说法是“一个人会意识到他们无法找到解决方案,除非靠运气并在几分钟后放弃”。

标签: php arrays algorithm sorting


【解决方案1】:

好的,我可能错过了一个“正确”的方法,但我仍然有一些解决方案。

无限搜索 - 尝试 2(推荐):

function get_parts3($arr,$target)
{
    foreach($arr as $k => $v)
    {
        if($v>$target) continue;
        foreach($arr as $k2 => $v2)
        {
            if($v2>$target) continue;
            if($k2==$k) continue;
            if($v + $v2 == $target)
            {
                return array($k,$k2);
            }
        }
        $tmparr = $arr;
        $tmparr[$k] = $target+1;
        $test = get_parts3($tmparr,$target-$v);
        if(is_array($test))
        {
            return array_merge(array($k),$test);
        }
    }
    return false;
}

尝试了无限搜索 1 - 但在大型数组上可能会出现性能问题。

function get_parts2($arr,$target)
{
    foreach($arr as $k => $v)
    {
        if($v > $target) continue;
        $keys = array_keys($arr);
        for($i=0;$i<25;$i++)
        {
            $sum = $v;
            $parts = array();
            $parts[$k] = $v;
            foreach($keys as $k2)
            {
                if($k2 == $k) continue;
                $v2 = $arr[$k2];
                if($sum+$v2 > $target) continue;
                $sum += $v2;
                $parts[$k2] = $v2;
                if($sum==$target) return array_keys($parts);
            }
            shuffle($keys);
        }
    }
    return false;
}

有限搜索(在本例中为 2 或 3 个数字的组合):

function get_parts($arr,$target)
{
    foreach($arr as $k => $v)
    {
        if($v>$target) continue;
        foreach($arr as $k2 => $v2)
        {
            if($v2>$target) continue;
            if($k2==$k) continue;
            if($v + $v2 == $target)
            {
                return array($v,$v2);
            }
            foreach($arr as $k3 => $v3)
            {
                if($v3>$target) continue;
                if($k3==$k2 || $k3==$k) continue;
                if($v + $v2 + $v3 == $target)
                {
                    return array($k,$k2,$k3);
                }
            }
        }
    }
    return false;
}

【讨论】:

  • 酷,解决 1 或 2 的有限搜索的解决方案 get_parts 有效,我可以在我的程序中使用它。谢谢,这是一个很好的解决方案。在 get_parts2 我认为你会重复数字,所以我可以添加一些代码来尝试区分它们......但是很好的代码......欣赏它:-)
  • @ConorRyan 不用担心,get_parts3 通常比 get_parts2 好,但我将它保留在那里作为备用解决方案,以备不时之需。
  • @ConorRyan 如果这回答了您的问题,请记住通过接受答案将问题标记为已解决(单击投票箭头下方的勾号)
  • @SmokeyPHP 嗨,我找到了你的代码,因为我需要它来完成它的工作,但是我很难理解它,当它变得疯狂时,get_parts3 的最后一部分,$tmparr = $arr; $tmparr[$k] = $目标+1; $test = get_parts3($tmparr,$target-$v); if(is_array($test)){ echo "Returneo
    .";返回 array_merge(array($k),$test);为什么你将 1 添加到目标,以及如何在函数中调用函数,我不知道这是可能的。返回 false 不会结束函数,介意解释一下吗?我通常可以理解任何代码,但这超出了我的能力。
  • @SmokeyPHP Nvm 伙计,我一直盯着它看,一遍又一遍地检查它,并设法完全解开它,谢谢你的代码!
猜你喜欢
  • 1970-01-01
  • 2011-11-30
  • 1970-01-01
  • 1970-01-01
  • 2011-03-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-20
相关资源
最近更新 更多