Подтвердить что ты не робот

Найти число, которое больше или равно N в массиве

Если у меня есть массив PHP:

$array

Со значениями:

45,41,40,39,37,31

И у меня есть переменная:

$number = 38;

Как я могу вернуть значение?:

39

Поскольку это самое близкое значение до 38 (подсчет) в массиве?

Привет,

Тэйлора

4b9b3361

Ответ 1

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

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

Ответ 2

Вот высокоуровневый процесс для получения желаемых результатов и работы для любых данных массива:

  • Отфильтруйте массив, сохраняя значения, превышающие или равные цели, и затем выберите самое низкое оставшееся значение. Это "лучшее" значение (которое может быть "ничего", если все значения были меньше) - это O(n)
  • В качестве альтернативы сначала выполните сортировку данных и см. ниже - это O(n lg n) (надеюсь)

Теперь, предполагая, что массив отсортирован в ASCENDING, этот подход будет работать:

  • Прокрутите массив и найдите первый элемент, который больше или равен цели - это O(n)

И если массив DESCENDING (как в сообщении), выполните действия, описанные выше, но либо:

  • Итерация назад - это O(n)
  • Отсортировать его сначала (см. fardjad answer) - это O(n lg n) (надеюсь)
  • Итерации вперед, но сохраняйте обратную сторону (чтобы запомнить "следующий максимум", если точное было пропущено) - это O(n)

Счастливое кодирование.

Ответ 3

EDIT опечатка на array_search

Эй... Кажется, достаточно легко. Здесь функция

<?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;
}

для запуска echo closest($array, 38);

Ответ 4

Здесь используется меньшая функция, которая также вернет ближайшее значение. Полезно, если вы не хотите сортировать массив (чтобы сохранить ключи).

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;
}

Ответ 5

Проведите линейное сканирование каждого номера и обновите две переменные, и вы сделаете это.

Код 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

При необходимости добавьте нулевые проверки.

Ответ 6

Если вы действительно хотите, чтобы значение, "ближайшее" на расстоянии, даже если оно меньшее значение, попробуйте это, что @Jason получает большую часть кредита.

Представьте себе сценарий, когда вы хотите, чтобы самое близкое число до 38.9:

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

Большинство решений здесь дадут вам 39,5, когда 38,5 намного ближе. Это решение будет принимать только самое высокое значение, если то, что вы ищете, находится в точной середине между двумя числами в массиве:

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];
    }
}
}

То, что ему не хватает в элегантности, это компенсируется точностью. Опять же, спасибо @Jason.

Ответ 7

Попробуйте эту простую функцию PHP:

<?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));
?>

Ответ 8

Я сделал для этого более короткую функцию:

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];
}

Отлично работает в моем случае: $array = array(128,160,192,224,256,320); $num = 203:)

Принимая самое ближайшее число, и если там будет такое же расстояние между двумя номерами (например, 208 для моего примера), используется следующий самый высокий номер.

Ответ 9

+1 Джейсону.

Моя реализация ниже, но не так, как быстрая

$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));

Ответ 10

Вы можете использовать array_reduce для этого, что делает его более функциональным, стиль программирования:

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

В остальном это следует тому же принципу, что и другие решения O (n).

Ответ 11

Вот мое решение.

$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;