简体   繁体   English

在数组中查找大于或等于 N 的数

[英]Find number which is greater than or equal to N in an array

If I have a PHP array:如果我有一个 PHP 阵列:

$array

With values:有价值观:

45,41,40,39,37,31

And I have a variable:我有一个变量:

$number = 38;

How can I return the value?:如何返回值?:

39

Because that is the closest value to 38 (counting up) in the array?因为那是数组中最接近 38(向上计数)的值?

Regards,问候,

taylor泰勒

<?php
function closest($array, $number) {

    sort($array);
    foreach ($array as $a) {
        if ($a >= $number) return $a;
    }
    return end($array); // or return NULL;
}
?>

Here is a high-level process to get the desired results and work for any array data:这是获得所需结果并适用于任何数组数据的高级过程:

  • Filter the array keeping on values greater than or equal to the target and then select the lowest remaining value.过滤数组,保持大于或等于目标的值,然后 select 最低剩余值。 This is the "best" value (which may be "nothing" if all the values were less) -- this is O(n)这是“最佳”值(如果所有值都较小,则可能是“无”)——这是O(n)
  • Alternatively, sort the data first and see below -- this is O(n lg n) (hopefully)或者,先对数据进行排序,然后看下面——这是O(n lg n) (希望如此)

Now, assuming that the array is sorted ASCENDING, this approach would work:现在,假设数组按 ASCENDING 排序,这种方法可行:

  • Loop through the array and find the first element which is larger than or equal to the target -- this is O(n)遍历数组并找到大于或等于目标的第一个元素 - 这是O(n)

And if the array is DESCENDING (as in the post), do as above, but either:如果数组是 DESCENDING (如帖子中所示),请按上述方式执行,但要么:

  • Iterate backwards -- this is O(n)向后迭代——这是O(n)
  • Sort it ASCENDING first (see fardjad's answer) -- this is O(n lg n) (hopefully)首先对它进行排序(参见 fardjad 的回答)——这是O(n lg n) (希望如此)
  • Iterate forwards but keep a look-behind value (to remember "next highest" if the exact was skipped) -- this is O(n)向前迭代但保留一个后视值(如果精确被跳过,请记住“下一个最高值”)——这是O(n)

Happy coding.快乐编码。

EDIT typo on array_search编辑array_search 上的错字

Yo... Seems easy enough.哟...似乎很容易。 Here's a function这是 function

<?php 
$array = array(45,41,40,39,37,31);

   function closest($array, $number){
    #does the array already contain the number?
    if($i = array_search( $number, $array)) return $i;

    #add the number to the array
    $array[] = $number;

    #sort and refind the number
    sort($array);
    $i = array_search($number, $array);

    #check if there is a number above it
    if($i && isset($array[$i+1])) return $array[$i+1];

    //alternatively you could return the number itself here, or below it depending on your requirements
    return null;
}

to Run echo closest($array, 38);运行echo closest($array, 38);

Here's a smaller function that will also return the closest value.这是一个较小的 function 也将返回最接近的值。 Helpful if you don't want to sort the array (to preserve keys).如果您不想对数组进行排序(以保留键),这很有帮助。

function closest($array, $number) {
    //does an exact match exist?
    if ($i=array_search($number, $array)) return $i;

    //find closest
    foreach ($array as $match) {
        $diff = abs($number-$match); //get absolute value of difference
        if (!isset($closeness) || (isset($closeness) && $closeness>$diff)) {
            $closeness = $diff;
            $closest = $match;
        }
    }
    return $closest;
}

Do a linear scan of each number and update two variables and you'll be done.对每个数字进行线性扫描并更新两个变量,你就完成了。

Python code (performance is O(N), I don't think it's possible to beat O(N)): Python 代码(性能为 O(N),我认为不可能击败 O(N)):

def closestNum(numArray, findNum):
    diff = infinity       # replace with actual infinity value
    closestNum = infinity # can be set to any value
    for num in numArray:
        if((num - findNum) > 0 and (num - findNum) < diff):
            diff = num - findNum
            closestNum = num
    return closestNum

Please add null checks as appropriate.请酌情添加 null 检查。

If you really want the value that's "closest" in distance, even if it's a lesser value, try this, which @Jason gets most of the credit for.如果你真的想要距离上“最接近”的值,即使它的值较小,试试这个,@Jason 得到了大部分的赞誉。

Imagine a scenario when you want the closest number to 38.9 in the following:想象一个场景,当您希望在以下情况下最接近 38.9 的数字:

$array = array(37.5, 38.5, 39.5);

Most of the solutions here would give you 39.5, when 38.5 is much closer.当 38.5 更接近时,这里的大多数解决方案都会给你 39.5。 This solution would only take the next highest value if what you're looking is in the exact middle between two numbers in the array:如果您正在查找的内容恰好位于数组中两个数字之间的中间,则此解决方案只会采用下一个最大值:

function nearest_value($value, $array) {
if (array_search($value, $array)) {
    return $value;
} else {
    $array[] = $value;
    sort($array);
    $key = array_search($value, $array);
    if ($key == 0) { return $array[$key+1]; }
    if ($key == sizeof($array)-1) { return $array[$key-1]; }
    $dist_to_ceil = $array[$key+1]-$value;
    $dist_to_floor = $value-$array[$key-1];
    if ($dist_to_ceil <= $dist_to_floor) {
        return $array[$key+1];
    } else {
        return $array[$key-1];
    }
}
}

What it lacks in elegance, it makes up for in accuracy.它缺乏优雅,它弥补了准确性。 Again, much thanks to @Jason.再次感谢@Jason。

Try this simple PHP function:试试这个简单的 PHP function:

<?php
function nearest($number, $numbers) {
    $output = FALSE;
    $number = intval($number);
    if (is_array($numbers) && count($numbers) >= 1) {
        $NDat = array();
        foreach ($numbers as $n)
            $NDat[abs($number - $n)] = $n;
        ksort($NDat);
        $NDat   = array_values($NDat);
        $output = $NDat[0];
    }
    return $output;
}

echo nearest(90, array(0, 50, 89, 150, 200, 250));
?>

I made a shorter function for that:为此,我制作了一个较短的 function:

function nearestNumber($num, $array) {
    if(!in_array($num, $array)) $array[] = $num;
    sort($array);
    $idx = array_search($num, $array);
    if(($array[$idx] -$array[$idx-1]) >= ($array[$idx+1] -$array[$idx])) return $array[$idx+1];
    else return $array[$idx-1];
}

Works great in my case: $array = array(128,160,192,224,256,320); $num = 203在我的情况下效果很好: $array = array(128,160,192,224,256,320); $num = 203 $array = array(128,160,192,224,256,320); $num = 203 :) $array = array(128,160,192,224,256,320); $num = 203 :)

It's taking the nearest number and if there's the same distance between two numbers (like 208 for my example), the next highest number is used.它采用最接近的数字,如果两个数字之间的距离相同(例如我的示例中的 208),则使用下一个最大的数字。

+1 to Jason. +1 给杰森。

My implementation below, but not as brisk我在下面的实现,但没有那么快

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

function closest($array, $number) {
    $array = array_flip($array);

    if(array_key_exists($number, $array)) return $number;

    $array[$number] = true;

    sort($array);

    $rendered = array_slice($array, $number, 2, true); 

    $rendered = array_keys($rendered);

    if(array_key_exists(1, $rendered)) return $rendered[1]; 

    return false;
}

print_r(closest($array, 3));

You could use array_reduce for this, which makes it more functional programming style:您可以为此使用array_reduce ,这使其更具函数式编程风格:

function closest($needle, $haystack) {
    return array_reduce($haystack, function($a, $b) use ($needle) {
        return abs($needle-$a) < abs($needle-$b) ? $a : $b;
    });
}

For the rest, this follows the same principle as the other O(n) solutions.对于 rest,这遵循与其他O(n)解决方案相同的原理。

Here is my solution.这是我的解决方案。

$array=array(10,56,78,17,30);
$num=65;
$diff=$num;
$min=$num;

foreach($array as $a){
          if( abs($a-$num)< $diff ){
              $diff=abs($a-$num);
              $min=$a;
          }
}

echo $min;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM