【问题标题】:Find nearest sum of numbers in array to a given number查找数组中最接近给定数字的数字总和
【发布时间】:2019-11-18 16:00:17
【问题描述】:

假设我有一个array [10000,5000,1000,1000],我想找到与给定数字最接近的数字总和。抱歉解释不好,但这里有一个例子:

假设我有一个array [10000,5000,1000,1000],我想找到最接近的数字,例如 6000

那么该方法应该返回 5000 和 1000

另一个例子:我们想要最接近 14000 ,那么他应该返回 10000 和 5000

我在这里尝试过 php,但是当我输入 6000 时出现问题,我应该得到 5000 和 1000

<?php

$arr    = [10000,5000,1000,1000];
$x      = 6000;
var_dump(eek($x,$arr));

function eek($x,$arr)
{
    $index = [];
    $counter = 0;
    foreach($arr as $val)
    {
        if($counter + $val <= $x)
        {
            $counter += $val;
            $index[] = $val;
        }
        elseif($counter + $val >= $x)
        {
            $counter += $val;
            $index[] = $val;
            break;
        }
    }

    if($counter == $x)
    {
        return $index;
    }
    elseif($counter >= $x)
    {
        return $index;    
    }
    else
    {
        return [];
    }
}

?>

有人有解决办法吗?

【问题讨论】:

  • 这是我工作上的问题,我已经积累了 2 天
  • @N69S 他的作业他有没有试过解决它不是吗?
  • @user3532758,谢谢老兄对我的欣赏……他这么说可能是因为我在这里没有名声,假设我是学生……
  • 甚至还有一个 PHP 实现:geeksforgeeks.org/…
  • 听起来像是测试驱动开发的绝佳训练集。如果返回其他内容,您尝试调试什么问题?

标签: php combinations


【解决方案1】:

考虑到数组是从大到小排序的

这里有一个解决方案,从你的开始

function eek($x,$arr)
{
    $index = [];
    $counter = 0;
    foreach($arr as $key => $val) {
        if($counter + $val < $x) {
            $counter += $val;
            $index[] = $val;
        } else {
            if (isset($arr[$key+1]) && (abs($counter + $arr[$key+1] -$x) < abs($counter + $val -$x))) {
                continue;
            } else {
                $index[] = $val;
                return $index;
            }
        }
    }

    return $index;
}

【讨论】:

  • @Aaron 请记住,这不是一个完美的解决方案,我只是优化了您开始使用的内容。
【解决方案2】:

这里适用于浮点数和负值:

$numbers = array(
    10000,5000,1000,1000
);
$desiredSum = 6000;
$minDist = null;
$minDist_I = null;
// Iterate on every possible combination
$maxI = pow(2,sizeof($numbers));
for($i=0;$i<$maxI;$i++) {
    if(!(($i+1) % 1000)) echo ".";

    // Figure out which numbers to select in this 
    $sum = 0;
    for($j=0;$j<sizeof($numbers);$j++) {
        if($i & (1 << $j)) {
            $sum += $numbers[$j];
        }
    }
    $diff = abs($sum - $desiredSum);
    if($minDist_I === null || $diff < $minDist) {
        $minDist_I = $i;
        $minDist = $diff;
    }

    if($diff == 0) break;
}
$chosen = array();
for($j=0;$j<sizeof($numbers);$j++) {
    if($minDist_I & (1 << $j)) $chosen[] = $numbers[$j];
}
echo "\nThese numbers sum to " . array_sum($chosen)  . " (closest to $desiredSum): ";
echo implode(", ", $chosen);
echo "\n";

【讨论】:

  • 欢迎它会工作,即使它充满了负浮点数和无序值
  • 先生,为什么当我尝试大型阵列时,为什么它运行非常缓慢,直到 php 执行超时...你有什么解决方案吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-14
  • 2021-08-09
  • 2012-12-27
  • 1970-01-01
相关资源
最近更新 更多