6

一部の数値が欠落している場合とない場合がある整数の範囲があります。ループ構造を使用せずに最小の欠落数を見つけることは可能ですか? 欠落している数値がない場合、関数は範囲の最大値に 1 を加えた値を返す必要があります。

これは、forループを使用して解決した方法です。

$range = [0,1,2,3,4,6,7];

// sort just in case the range is not in order
asort($range);
$range = array_values($range);

$first = true;
for ($x = 0; $x < count($range); $x++)
{
    // don't check the first element
    if ( ! $first )
    {
        if ( $range[$x - 1] + 1 !== $range[$x])
        {
            echo $range[$x - 1] + 1;
            break;
        }
    }

    // if we're on the last element, there are no missing numbers
    if ($x + 1 === count($range))
    {
        echo $range[$x] + 1;
    }
    $first = false;
}

理想的には、範囲が膨大になる可能性があるため、完全にループすることは避けたいと思います。助言がありますか?

4

10 に答える 10

5

正直なところ、ループを使用したくない理由がわかりません。ループに問題はありませんそれらは高速であり、それらなしでは済まされません。ただし、あなたの場合、PHP コア関数を使用して、独自のループを作成する必要を回避する方法があります。ただし、それらは配列をループしますが、それを避けることはできません。
とにかく、私はあなたが求めているものを集めます.3行で簡単に書くことができます:

function highestPlus(array $in)
{
    $compare = range(min($in), max($in));
    $diff = array_diff($compare, $in);
    return empty($diff) ? max($in) +1 : $diff[0];
}

テスト済み:

echo highestPlus(range(0,11));//echoes 12
$arr = array(9,3,4,1,2,5);
echo highestPlus($arr);//echoes 6

そして今、恥知らずにペ・デ・レオンの答えを盗むために(しかし、あなたが望むことを正確に行うためにそれを「増強」してください):

function highestPlus(array $range)
{//an unreadable one-liner... horrid, so don't, but know that you can...
     return min(array_diff(range(0, max($range)+1), $range)) ?: max($range) +1;
}

使い方:

$compare = range(min($in), max($in));//range(lowest value in array, highest value in array)
$diff = array_diff($compare, $in);//get all values present in $compare, that aren't in $in
return empty($diff) ? max($in) +1 : $diff[0];
//-------------------------------------------------
// read as:
if (empty($diff))
{//every number in min-max range was found in $in, return highest value +1
    return max($in) + 1;
}
//there were numbers in min-max range, not present in $in, return first missing number:
return $diff[0];

それだけです、本当に。
もちろん、提供された配列に値または文字列が含まれていてnull、値が重複している可能性がある場合は、入力を少し「クリーン」falsyにすることが役立つ場合があります。

function highestPlus(array $in)
{
    $clean = array_filter(
        $in,
        'is_numeric'//or even is_int
    );
    $compare = range(min($clean), max($clean));
    $diff = array_diff($compare, $clean);//duplicates aren't an issue here
    return empty($diff) ? max($clean) + 1; $diff[0];
}

便利なリンク:

于 2013-08-18T17:42:49.597 に答える
3
$range = array(0,1,2,3,4,6,7);    
// sort just in case the range is not in order
asort($range);
$range = array_values($range);
$indexes = array_keys($range);
$diff = array_diff($indexes,$range);

echo $diff[0]; // >> will print: 5 
// if $diff is an empty array - you can print 
// the "maximum value of the range plus one": $range[count($range)-1]+1
于 2013-08-15T22:10:22.827 に答える
1
$range = array(0,1,2,3,4,6,7);

$max=max($range);

$expected_total=($max*($max+1))/2; // sum if no number was missing.

$actual_total=array_sum($range);  // sum of the input array.

if($expected_total==$actual_total){
   echo $max+1;      // no difference so no missing number, then echo 1+ missing number.
}else{
   echo $expected_total-$actual_total; // the difference will be the missing number.
}
于 2013-08-20T07:29:42.507 に答える
1
echo min(array_diff(range(0, max($range)+1), $range));
于 2013-08-16T11:34:17.417 に答える