Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/292.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PHP未排序数组和的最大整数_Php_Math_Sum - Fatal编程技术网

PHP未排序数组和的最大整数

PHP未排序数组和的最大整数,php,math,sum,Php,Math,Sum,有人能告诉我从未排序数组求和的最大整数的最佳方法吗 e、 g 谢谢 更新 我已经接受了我使用的方法,但是下面的一些方法在编程上是正确的 $array=array(0.1, 0.2, 0.9, 0.5); arsort($array); while($highest=array_shift($array)){ foreach($array as $val){ $thisval=($highest+val); if(round($thisval)==($thisval))

有人能告诉我从未排序数组求和的最大整数的最佳方法吗

e、 g

谢谢

更新

我已经接受了我使用的方法,但是下面的一些方法在编程上是正确的

 $array=array(0.1, 0.2, 0.9, 0.5);
 arsort($array);
 while($highest=array_shift($array)){
   foreach($array as $val){
    $thisval=($highest+val);
    if(round($thisval)==($thisval)){
     return $thisval;
   }
 }
}

编辑:@Felix Kling你完全正确,添加了一个while循环

我还没有为此编写代码,但psuedo代码如下。一般的想法是计算组合(x选择y…),然后对每个组合求和。对数组的长度进行迭代,然后取最大值

我还确信,对于贪婪和短路这个循环,也有一些优化

$len = count($decimals);
$maxVals = array();

for( $choose = $len; $choose > 1; $choose-- ) {
    // get $decimals choose $choose

    // loop and sum each choose array, checking for an integer sum

    // store max if exists
}

return sum($maxVals);
好好想想

$sum = array_sum($arr);
$floor_sum = floor($sum);
if ($sum = $floor_sum){
return $sum
}else{

for ($i = 0; $i < sizeof($arr); $i++){
  if ($sum - $arr[$i] = $floor_sum){
     return $sum - $arr[i];
  }else{
    for ($x = 0; $x < sizeof($arr)- 1; $x++){
      if ($x != $i){
        if ($sum - $arr[$i] - $arr[$x] = $floor_sum){
         return $sum - $arr[$i] - $arr[$x];
        }else {
            //Iterate more times
        }
      }
    }
  }
}

}
$sum=array\u sum($arr);
$floor_sum=地板($sum);
如果($sum=$floor\u sum){
返回$sum
}否则{
对于($i=0;$i

我有上面的内容,但一定有更简单的方法来实现它?

这段代码的大部分是用于获取数组的排列。我相信它是可以优化的,但这是在四核单Xeon服务器上计算3个阵列,长度分别为4、5和6英寸45毫秒。当我加上第四个数组(7个小数)和第五个数组(8个小数)时,跳到大约220毫秒

基本上,所有这些操作都是获取包含浮点数的数组的所有排列,逐键将每个排列相加,如果总和是大于当前整数的整数,则更新该数字。。最终返回可能的最大数量

$set1 = array(0.1, 0.2, 0.9, 0.5);
$set2 = array(0.9, 0.2, 0.5, 0.3, 0.9);
$set3 = array(0.9, 0.2, 0.5, 0.3, 0.9, 0.4);

function largestWholeNumber($decimals){
    echo "Calculating largest whole number for decimal set '"
    . implode(",", $decimals)
    . "'<br />";
    $perms = perms($decimals);
    $answer = 0;
    foreach($perms as $dec_array){
        $current_guess = 0;
        foreach($dec_array as $dec){
            $current_guess += $dec;
            if (!preg_match("/[^0-9]+/", $current_guess)){
                if ($answer < $current_guess){
                    $answer = $current_guess;
                    echo "New whole number found " 
                    ."'$answer'"
                    ." with permutation: <br />";
                    print_r($dec_array);
                    echo "<br />";
                }
            }
        }
    }
    echo "Result: $answer<br /><br />";
    return $answer;
}

function factorial($int){
if($int < 2) {
       return 1;
}

for($f = 2; $int-1 > 1; $f *= $int--);

return $f;
}


function perms($arr) {
    $p = array();
    for ($i=0; $i < factorial(count($arr)); $i++) {
        $p[] = perm($arr, $i);
    }
    return $p;
}


function perm($arr, $nth = null) {

    if ($nth === null) {
        return perms($arr);
    }

    $result = array();
    $length = count($arr);

    while ($length--) {
        $f = factorial($length);
        $p = floor($nth / $f);
        $result[] = $arr[$p];
        array_delete_by_key($arr, $p);
        $nth -= $p * $f;
    }

    $result = array_merge($result,$arr);
    return $result;
}
function array_delete_by_key(&$array, $delete_key, $use_old_keys = FALSE) {

    unset($array[$delete_key]);

    if(!$use_old_keys) {
        $array = array_values($array);
    }

    return TRUE;
}

largestWholeNumber($set1); // 1
largestWholeNumber($set2); // 2
largestWholeNumber($set3); // 3
$set1=数组(0.1,0.2,0.9,0.5);
$set2=数组(0.9,0.2,0.5,0.3,0.9);
$set3=数组(0.9,0.2,0.5,0.3,0.9,0.4);
函数最大整数($decimals){
echo“计算十进制集合的最大整数”
.内爆(“,”,$decimals)
.“
”; $perms=perms($decimals); $answer=0; foreach($perms作为$dec_数组){ $current_guess=0; foreach($dec_数组作为$dec){ $current_guess+=$dec; 如果(!preg_match(“/[^0-9]+/”,$current_guess)){ 如果($answer<$current\u guess){ $answer=$current\u guess; 回显“找到新整数” “$answer” “带排列:
”; 打印($dec_数组); 回声“
”; } } } } echo“结果:$answer

”; 返回$answer; } 函数阶乘($int){ 如果($int<2){ 返回1; } 对于($f=2;$int-1>1;$f*=$int--); 返回$f; } 函数perms($arr){ $p=array(); 对于($i=0;$i

数组置换函数的功劳归于
dirk dot avery a t gmail
at
http://php.net/manual/en/function.shuffle.php

这是一个值得思考的大问题。在我脑海中,我会使用以下伪代码:

  • A=元素数组
  • '=元素的排序数组
  • S=所有元素的总和
  • 虽然A'不是空的:
  • V=S的整数部分
  • R=S的剩余部分=S-楼层
  • 制作a',X的临时副本
  • 将X的最大值迭代为X[i]:
  • 如果X[i]
  • 如果R==0,我们已经找到了解决方案。V是整数,X包含加数。停下来
  • 如果X为空,则没有解决方案。停下来
  • 以A'中的最大值减少S。S=S-最大值(A')。从A'中删除最大值(A')
  • 返回到步骤4
  • 当然,我必须看看这是否真的有效。下面是我为测试它而编写的代码(非常混乱,质量很差):

    <?php
    $AA = $A = array(0.1, 0.2, 0.9, 0.5);
    
    bcscale(8);
    
    sort($AA, SORT_NUMERIC);
    echo 'A = ' . implode(', ', $A), PHP_EOL;
    echo 'A\' = ' . implode(', ', $AA), PHP_EOL;
    
    $S = array_sum($AA);
    echo 'S = ' . $S, PHP_EOL;
    
    while (count($AA)) {
        $V = floor($S);
        echo 'V = ' . $V, PHP_EOL;
    
        $R = bcsub($S, $V);
        echo 'R = ' . $R, PHP_EOL;
    
        $X = $AA;
        $XX = array();
    
        // Look for the largest value that is less than or equal to R.
        for ($i = count($X) - 1; $i >= 0; $i--) {
            echo 'X[i] = ' . $X[$i] . ', R = ' . $R, PHP_EOL;
            $c = bccomp($X[$i], $R);
            if ($c > 0) {
                continue;
            }
            $XX[] = $X[$i];
            $R = bcsub($R, $X[$i]);
            unset($X[$i]);
    
            if (bccomp($R, '0', strlen($R)) == 0) {
                echo 'Largest whole number sum: ' . $V, PHP_EOL;  
                echo 'Elements: ' . implode(', ', $X), PHP_EOL;   
                break 2;
            }
        }
    
        if (count($X) == 0) {
            echo 'No sums to a whole number are possible.', PHP_EOL;
            break;
        }
    
        $t = array_pop($AA);
        $S = bcsub($S, $t);
    }
    
    echo 'S = ' . $S, PHP_EOL;
    ?>
    
    
    
    这是一个丑陋的O(N^2)算法,但它应该是正确的。任何人都可以看到一个初始启动阵列,它将失败吗

    为了好玩,我尝试使用50个元素的数组,将第一行替换为以下几行:

    $A = array();
    for ($i = 0; $i < 50; $i++) {
        $A[] = mt_rand(1, 99) / 100.0;
    }
    $AA = $A;
    
    $A=array();
    对于($i=0;$i<50;$i++){
    $A[]=百万兰特(1,99)/100.0;
    }
    $AA=$A;
    

    乍一看,它看起来是正确的-我将把验证留给其他人;)

    我建议对整个数组求和,然后找到小数部分等于整个和的最小和。除非这些数字在小数点后有很高的精度,否则无论寻找精确数字的方法是什么,这种反转应该可以节省大量的计算


    此外,对数组进行排序并从最小的数字开始贪婪可能会产生很好的结果。然而,最优解非常依赖于初始集的性质。您能否提供更详细的规格说明,说明您期望的数字类型?

    Hhm我认为这与knap-sack问题有关:但是,可能有更好的解决方案,因为您比“0-1 kna”更严格
    $A = array();
    for ($i = 0; $i < 50; $i++) {
        $A[] = mt_rand(1, 99) / 100.0;
    }
    $AA = $A;