Php 如何在排序数组中查找最近的值?
我已经用数字作为键对数组进行了排序,我需要一个相当快的alg来选择一个键值,该键值与给定变量的值最接近或相同(如果存在)。如果给定值高于最大值或低于最小值,则分别给出保持最大值和最小值的键。您可以使用。假设您正在查找Php 如何在排序数组中查找最近的值?,php,arrays,Php,Arrays,我已经用数字作为键对数组进行了排序,我需要一个相当快的alg来选择一个键值,该键值与给定变量的值最接近或相同(如果存在)。如果给定值高于最大值或低于最小值,则分别给出保持最大值和最小值的键。您可以使用。假设您正在查找myVal 看看数组的中间值 如果值为myVal,则完成 如果该值高于myVal,请将数组一分为二并转到1,但仅使用数组的下半部分 如果该值较低,请转到1,但仅使用上半部分 一旦到达且数组的长度=1,将该值与其相邻值进行比较,以查看哪个值最接近 这应该是一个O(logn)搜索。您可以
myVal
myVal
,则完成myVal
,请将数组一分为二并转到1,但仅使用数组的下半部分myVal
myVal
,则完成myVal
,请将数组一分为二并转到1,但仅使用数组的下半部分这应该是一个O(logn)搜索。所以我做了一个尝试,这里有一个函数,可以将一个数组中的值转换为另一个数组中的值,它可以用于温度,例如,-10到冷或+30到热,但对于大数组,它不是很快,有什么线索可以让它更快吗
function transnum($nums,$transarr,$searchkey='x',$returnkey='y') {
$was_arr = is_array($nums); $nums = (array)$nums;
foreach ($nums as &$num) {
if ($num===null or $num==='') continue;
reset($transarr[$searchkey]);
$ckey= key($transarr[$searchkey]);
$closest = abs($num-current($transarr[$searchkey]));
while($next = next($transarr[$searchkey])) {
$checkclosest=abs($num-$next);
if($closest>$checkclosest) {
$closest = $checkclosest;
$ckey = key($transarr[$searchkey]);
}
else break;
}
$num = $transarr[$returnkey][$ckey];
}
if(!$was_arr) $nums = $nums[0];
return $nums;
}所以我尝试了一下,这里有一个函数,可以将一个数组中的值转换为另一个数组中的值,它可以用于温度,-10到冷或+30到热,但是对于大型数组,它并没有那么快,有没有线索可以让它更快
function transnum($nums,$transarr,$searchkey='x',$returnkey='y') {
$was_arr = is_array($nums); $nums = (array)$nums;
foreach ($nums as &$num) {
if ($num===null or $num==='') continue;
reset($transarr[$searchkey]);
$ckey= key($transarr[$searchkey]);
$closest = abs($num-current($transarr[$searchkey]));
while($next = next($transarr[$searchkey])) {
$checkclosest=abs($num-$next);
if($closest>$checkclosest) {
$closest = $checkclosest;
$ckey = key($transarr[$searchkey]);
}
else break;
}
$num = $transarr[$returnkey][$ckey];
}
if(!$was_arr) $nums = $nums[0];
return $nums;
}这是一个java实现,您可以将其翻译成您选择的语言
static int findNearestValue(int value, int arr[], int low, int high) {
int result = -1;
if(high-low>1){
int mid = low + (high-low)/2;
if(arr[mid]>value)
result = findNearestValue3(value, arr, low, mid);
else if(arr[mid]<value)
result = findNearestValue3(value, arr, mid, high);
else
result = arr[mid];
}else
result = (abs(value-arr[low]) < abs(value-arr[high])) ? arr[low] : arr[high];
return result;
}
静态int-findNearestValue(int-value,int-arr[],int-low,int-high){
int结果=-1;
如果(高-低>1){
int mid=低+(高-低)/2;
如果(arr[mid]>值)
结果=findNearestValue3(值、arr、低、中);
否则,如果(arr[mid]这是一个java实现,您可以将其翻译成您选择的语言
static int findNearestValue(int value, int arr[], int low, int high) {
int result = -1;
if(high-low>1){
int mid = low + (high-low)/2;
if(arr[mid]>value)
result = findNearestValue3(value, arr, low, mid);
else if(arr[mid]<value)
result = findNearestValue3(value, arr, mid, high);
else
result = arr[mid];
}else
result = (abs(value-arr[low]) < abs(value-arr[high])) ? arr[low] : arr[high];
return result;
}
静态int-findNearestValue(int-value,int-arr[],int-low,int-high){
int结果=-1;
如果(高-低>1){
int mid=低+(高-低)/2;
如果(arr[mid]>值)
结果=findNearestValue3(值、arr、低、中);
否则,如果(arr[mid]C代码:
#include <stdio.h>
#define moddiff(a,b) ((a > b) ? (a-b) : (b-a))
#define uint unsigned int
/* test case : sample array */
uint arr[] = { 1, 4, 9, 16, 25, 36, 49 , 64, 81 };
/* search for nearest num to key in a sorted array */
uint nrst_num(uint arr[], uint lo, uint hi, uint key)
{
uint mid = 0;
uint mid_parent = 0;
while (lo < hi) {
mid_parent = mid;
mid = (lo + hi) / 2;
if (key == arr[mid]) {
return mid;
} else if (key < arr[mid]) {
hi = mid - 1;
} else if (key > arr[mid]) {
lo = mid + 1;
}
}
uint ldiff = moddiff(key, arr[lo]);
uint mdiff = moddiff(key, arr[mid]);
uint hdiff = moddiff(key, arr[hi]);
uint mid_parent_diff = moddiff(key, arr[mid_parent]);
/* select the index from the lowest diff */
if ((mid_parent_diff <= mdiff) && (mid_parent_diff <= ldiff) && (mid_parent_diff <= hdiff)) {
return mid_parent;
} else if ((mdiff <= mid_parent_diff) && (mdiff <= ldiff) && (mdiff <= hdiff)) {
return mid;
} else if ((ldiff <= mdiff) && (ldiff <= hdiff) && (ldiff <= mid_parent_diff)) {
return lo;
}
return hi;
}
int main()
{
/* test case */
uint key = 0;
printf(" { 1, 4, 9, 16, 25, 36, 49 , 64, 81 }");
uint res = nrst_num(arr, 0, 8, key);
printf (" nearest point to key=%d is val=%d \n", key, res);
}
#包括
#定义moddiff(a,b)((a>b)?(a-b):(b-a))
#定义uint unsigned int
/*测试用例:示例数组*/
uint arr[]={1,4,9,16,25,36,49,64,81};
/*在排序数组中搜索最接近的num*/
uint nrst_num(uint arr[],uint lo,uint hi,uint key)
{
uint-mid=0;
uint mid_parent=0;
while(loarr[mid]){
lo=中间+1;
}
}
uint ldiff=moddiff(键,arr[lo]);
uint mdiff=moddiff(键,arr[mid]);
uint hdiff=moddiff(键,arr[hi]);
uint mid_parent_diff=moddiff(键,arr[mid_parent]);
/*从最低差异中选择索引*/
如果((中间父项差异C代码:
#include <stdio.h>
#define moddiff(a,b) ((a > b) ? (a-b) : (b-a))
#define uint unsigned int
/* test case : sample array */
uint arr[] = { 1, 4, 9, 16, 25, 36, 49 , 64, 81 };
/* search for nearest num to key in a sorted array */
uint nrst_num(uint arr[], uint lo, uint hi, uint key)
{
uint mid = 0;
uint mid_parent = 0;
while (lo < hi) {
mid_parent = mid;
mid = (lo + hi) / 2;
if (key == arr[mid]) {
return mid;
} else if (key < arr[mid]) {
hi = mid - 1;
} else if (key > arr[mid]) {
lo = mid + 1;
}
}
uint ldiff = moddiff(key, arr[lo]);
uint mdiff = moddiff(key, arr[mid]);
uint hdiff = moddiff(key, arr[hi]);
uint mid_parent_diff = moddiff(key, arr[mid_parent]);
/* select the index from the lowest diff */
if ((mid_parent_diff <= mdiff) && (mid_parent_diff <= ldiff) && (mid_parent_diff <= hdiff)) {
return mid_parent;
} else if ((mdiff <= mid_parent_diff) && (mdiff <= ldiff) && (mdiff <= hdiff)) {
return mid;
} else if ((ldiff <= mdiff) && (ldiff <= hdiff) && (ldiff <= mid_parent_diff)) {
return lo;
}
return hi;
}
int main()
{
/* test case */
uint key = 0;
printf(" { 1, 4, 9, 16, 25, 36, 49 , 64, 81 }");
uint res = nrst_num(arr, 0, 8, key);
printf (" nearest point to key=%d is val=%d \n", key, res);
}
#包括
#定义moddiff(a,b)((a>b)?(a-b):(b-a))
#定义uint unsigned int
/*测试用例:示例数组*/
uint arr[]={1,4,9,16,25,36,49,64,81};
/*在排序数组中搜索最接近的num*/
uint nrst_num(uint arr[],uint lo,uint hi,uint key)
{
uint-mid=0;
uint mid_parent=0;
while(loarr[mid]){
lo=中间+1;
}
}
uint ldiff=moddiff(键,arr[lo]);
uint mdiff=moddiff(键,arr[mid]);
uint hdiff=moddiff(键,arr[hi]);
uint mid_parent_diff=moddiff(键,arr[mid_parent]);
/*从最低差异中选择索引*/
if((mid_parent_diff)我认为该算法没有给出最接近的值。最接近的值可能与返回的值相邻。反例是:[1,3,10],搜索最接近4的值。第一个中间值是3,然后是子数组[10]被考虑,并返回10。但是,最近的值实际上是3。我同意李杰的观点,但你可以调整二进制搜索以获得最近的值:每次你到一半,你都会在一半中包含上一个选中的数字。当你的子集达到计数2时,你会选择两个中更接近的值。我认为该算法不适用于g选择最接近的值。最接近的值可能与返回的值相邻。反例是:[1,3,10],搜索与4最接近的值。第一个中间值是3,然后是子数组[10]被考虑,并返回10。但是,最接近的值实际上是3。我同意李杰的观点,但你可以调整二进制搜索以获得最接近的值:每次你到一半,你都会在一半中包含上一个选中的数字。当你的子集达到计数2时,你会选择两个中更接近的值。可能重复的可能是d副本