今天我被问到在一个集合中找到最接近匹配的最佳方法是什么。
例如,你有这样一个数组:
1, 3, 8, 10, 13, ...
离4最近的数字是多少?
集合是数值、无序且可以是任何东西。匹配的数字也是如此。
让我们看看从各种语言中能够得到什么结果。
今天我被问到在一个集合中找到最接近匹配的最佳方法是什么。
例如,你有这样一个数组:
1, 3, 8, 10, 13, ...
离4最近的数字是多少?
集合是数值、无序且可以是任何东西。匹配的数字也是如此。
让我们看看从各种语言中能够得到什么结果。
J 中的 11 字节:
C=:0{]/:|@-
举例:
>> a =: 1 3 8 10 13
>> 4 C a
3
>> 11 C a
10
>> 12 C a
13
对于普通人的解释:
0{ First element of
] the right argument
/: sorted by
| absolute value
@ of
- subtraction
更短的 Python 代码:41 个字符
f=lambda a,l:min(l,key=lambda x:abs(x-a))
我的Python尝试:
def closest(target, collection) :
return min((abs(target - i), i) for i in collection)[1]
Groovy 28B
f={a,n->a.min{(it-n).abs()}}
以下是一些与C# Linq有关的内容... 有太多的方法可以做到这一点!
decimal[] nums = { 1, 3, 8, 12 };
decimal target = 4;
var close1 = (from n in nums orderby Math.Abs(n-target) select n).First();
var close2 = nums.OrderBy(n => Math.Abs(n - target)).First();
Console.WriteLine("{0} and {1}", close1, close2);
如果您使用列表,将有更多的方法,因为普通数组没有 .Sort() 方法。
因为我确实需要这样做,所以这是我的PHP代码:
$match = 33;
$set = array(1,2,3,5,8,13,21,34,55,89,144,233,377,610);
foreach ($set as $fib)
{
$diff[$fib] = (int) abs($match - $fib);
}
$fibs = array_flip($diff);
$closest = $fibs[min($diff)];
echo $closest;
select*from(select*from t order by abs(n-4))where rownum=1
PostgreSQL:
select n from tbl order by abs(4 - n) limit 1
如果两个记录共享“abs(4-id)”的相同值,则输出将是不确定的,可能不是一个常数。为了解决这个问题,我建议尝试以下未经测试的猜测:
select n from tbl order by abs(4 - n) + 0.5 * 4 > n limit 1;
这个解决方案的性能大约是O(N log N),其中O(log N)也是可能的,例如:https://dev59.com/snRB5IYBdhLWcg3w-8Ho#8900318
就像 Python 一样,Ruby 也有一个用于 Enumerable 的 min 方法,因此您不需要进行排序操作。
def c(value, t_array)
t_array.min{|a,b| (value-a).abs <=> (value-b).abs }
end
ar = [1, 3, 8, 10, 13]
t = 4
c(t, ar) = 3
上述代码对浮点数无效。
因此,以下是我修改后的 PHP 代码。
function find_closest($match, $set=array()) {
foreach ($set as $fib) {
$diff[$fib] = abs($match - $fib);
}
return array_search(min($diff), $diff);
}
$set = array('2.3', '3.4', '3.56', '4.05', '5.5', '5.67');
echo find_closest(3.85, $set); //return 4.05