猿问
下载APP

在数组中查找匹配或最接近的值

在数组中查找匹配或最接近的值

对于给定的目标值,如何搜索和查找数组中最接近的值?

假设我有这个示例性数组:

array(0, 5, 10, 11, 12, 20)

例如,当我用目标值0搜索时,函数应返回0; 当我用3搜索时,它将返回5; 当我用14搜索时,它将返回12。


浮云间
浏览 70回答 3
3回答

交互式爱情

将您要搜索的数字作为第一个参数传递,将数字数组传递给第二个参数:function getClosest($search, $arr) {    $closest = null;    foreach ($arr as $item) {       if ($closest === null || abs($search - $closest) > abs($item - $search)) {          $closest = $item;       }    }    return $closest;}

茅侃侃

一种特殊的懒惰方法是让PHP按照搜索到的数字的距离对数组进行排序:$num = 3;    $array = array(0, 5, 10, 11, 12, 20);foreach ($array as $i) {     $smallest[$i] = abs($i - $num);}asort($smallest);print key($smallest);

开满天机

这是我为排序的大数组编写的高性能函数对于具有20000个元素的数组,经过测试的主循环仅需要~20次迭代。请注意数组必须排序(升序)!define('ARRAY_NEAREST_DEFAULT',&nbsp; &nbsp; 0);define('ARRAY_NEAREST_LOWER',&nbsp; &nbsp; &nbsp; 1);define('ARRAY_NEAREST_HIGHER',&nbsp; &nbsp; &nbsp;2);/**&nbsp;* Finds nearest value in numeric array. Can be used in loops.&nbsp;* Array needs to be non-assocative and sorted.&nbsp;*&nbsp;&nbsp;* @param array $array&nbsp;* @param int $value&nbsp;* @param int $method ARRAY_NEAREST_DEFAULT|ARRAY_NEAREST_LOWER|ARRAY_NEAREST_HIGHER&nbsp;* @return int&nbsp;*/function array_numeric_sorted_nearest($array, $value, $method = ARRAY_NEAREST_DEFAULT) {&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; $count = count($array);&nbsp; &nbsp; if($count == 0) {&nbsp; &nbsp; &nbsp; &nbsp; return null;&nbsp; &nbsp; }&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; $div_step&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= 2;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; $index&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = ceil($count / $div_step);&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; $best_index&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= null;&nbsp; &nbsp; $best_score&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= null;&nbsp; &nbsp; $direction&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = null;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; $indexes_checked&nbsp; &nbsp; &nbsp; &nbsp; = Array();&nbsp; &nbsp; while(true) {&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; if(isset($indexes_checked[$index])) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break ;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; $curr_key = $array[$index];&nbsp; &nbsp; &nbsp; &nbsp; if($curr_key === null) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break ;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; $indexes_checked[$index] = true;&nbsp; &nbsp; &nbsp; &nbsp; // perfect match, nothing else to do&nbsp; &nbsp; &nbsp; &nbsp; if($curr_key == $value) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return $curr_key;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; $prev_key = $array[$index - 1];&nbsp; &nbsp; &nbsp; &nbsp; $next_key = $array[$index + 1];&nbsp; &nbsp; &nbsp; &nbsp; switch($method) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; default:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case ARRAY_NEAREST_DEFAULT:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $curr_score = abs($curr_key - $value);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $prev_score = $prev_key !== null ? abs($prev_key - $value) : null;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $next_score = $next_key !== null ? abs($next_key - $value) : null;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if($prev_score === null) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $direction = 1;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }else if ($next_score === null) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break 2;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }else{&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $direction = $next_score < $prev_score ? 1 : -1;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case ARRAY_NEAREST_LOWER:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $curr_score = $curr_key - $value;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if($curr_score > 0) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $curr_score = null;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }else{&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $curr_score = abs($curr_score);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if($curr_score === null) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $direction = -1;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }else{&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $direction = 1;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case ARRAY_NEAREST_HIGHER:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $curr_score = $curr_key - $value;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if($curr_score < 0) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $curr_score = null;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if($curr_score === null) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $direction = 1;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }else{&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $direction = -1;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; if(($curr_score !== null) && ($curr_score < $best_score) || ($best_score === null)) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $best_index = $index;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $best_score = $curr_score;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; $div_step *= 2;&nbsp; &nbsp; &nbsp; &nbsp; $index += $direction * ceil($count / $div_step);&nbsp; &nbsp; }&nbsp; &nbsp; return $array[$best_index];}ARRAY_NEAREST_DEFAULT 找到最近的元素ARRAY_NEAREST_LOWER 找到最近的元素是LOWERARRAY_NEAREST_HIGHER 找到最接近的元素用法:$test = Array(5,2,8,3,9,12,20,...,52100,52460,62000);// sort an array and use array_numeric_sorted_nearest// for multiple searches.&nbsp;// for every iteration it start from half of chunk where// first chunk is whole array// function doesn't work with unosrted arrays, and it's much// faster than other solutions here for sorted arrayssort($test);$nearest = array_numeric_sorted_nearest($test, 8256);$nearest = array_numeric_sorted_nearest($test, 3433);$nearest = array_numeric_sorted_nearest($test, 1100);$nearest = array_numeric_sorted_nearest($test, 700);
打开App,查看更多内容
随时随地看视频慕课网APP
我要回答