我已经用数字作为键对数组进行了排序,我需要一个合理快速的算法来选择一个键值,该键值保持与给定变量最接近或相同(如果存在)的值。如果给定值高于最大值或低于最小值,则分别给出保持最大值和最小值的键。
答案 0 :(得分:3)
您可以使用binary search。假设您正在寻找myVal
myVal
,则表示您已完成。myVal
,请将数组拆分为一半并转到1,但仅使用数组的下半部分这应该是O(log N)搜索。
答案 1 :(得分:3)
这是一个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;
}
答案 2 :(得分:0)
所以我做了一个尝试,这里是一个函数,可以根据另一个数组转换一个数组中的值,它可以用于例如温度,-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;
}
答案 3 :(得分:0)
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);
}