我多年来一直在使用这个Excel公式。它工作正常,但我想了解它的工作原理!该公式用于在列表中查找 last 关联值。例如:
C14中的公式:=LOOKUP(2,1/(B1:B12="meat"),C1:C12)
此处,C14
中的公式在B列中查找最新的"meat"
标记的单元格,并返回C列中的关联值。它在"meat"
处找到B9
,并相应地返回C9
处的值。
公式中最令人费解的部分是"1/(....)"
。这个师是什么?这种语法来自哪里?可以在其他地方使用吗?为什么查找值为2
?
答案 0 :(得分:8)
这里发生了什么:这个
=LOOKUP(2,1/(B1:B12="meat"),C1:C12)
变成这个
=LOOKUP(2,1/{TRUE;FALSE;FALSE;FALSE;FALSE;FALSE;FALSE;FALSE;TRUE;FALSE;FALSE;FALSE},C1:C12)
成为这个
=LOOKUP(2,{1;#DIV/0!;#DIV/0!;#DIV/0!;#DIV/0!;#DIV/0!;#DIV/0!;#DIV/0!;1;#DIV/0!;#DIV/0!;#DIV/0!},C1:C12)
B1:B12="meat"
部分被评估为TRUE和FALSE值的数组。当您在TRUE或FALSE上进行数学运算时,它会变为1或0.将1乘1或0除以1表示所有结果,div / 0表示所有结果。
既然你知道你将拥有一个完全由两件事组成的阵列(1或者div / 0),你可以查看大于1的任何数字,它会返回列表中的最后一个。您可以=LOOKUP(800,...)
,它仍会返回小于或等于查找值"的最大值,或者在您的情况下为1。
所以这两者有点武断 - 它只是一个大于1的数字。它的关键是创建只包含1和错误的查找数组参数--LOOKUP忽略错误。
二进制搜索
我没有关于此的官方文档,所以这里是非官方版本。 LOOKUP,HLOOKUP和VLOOKUP有一个参数,告诉函数数据是否已排序。如果该参数为False,则该函数将一直查看每个条目,直到结束。如果该参数为True或省略,则该函数使用二进制搜索。这样做 - 论证只存在 - 因为二元搜索比ol'更快。一次一个搜索。
二元搜索的工作原理是找到中间值并根据搜索值对其进行评估。如果中间值较大,则右侧的所有内容都将被丢弃 - 所寻求的值必须在左侧。它需要左半部分并找到它的中间值。如果它更大,它会丢弃右边并保持左边。继续迭代,直到找到值。
那么为什么LOOKUP(2,{1,1,#DIV/0!,1,1,#DIV/0!,1,1},...)
会找到最后一个1
而不是某个1
?我不确切知道MS如何实现他们的二分搜索,所以我必须做出一些假设。我的假设是错误值被抛出数组,并且当存在偶数个条目(没有中间值)时,使用中间左侧的值。这些假设可能是错误的,但它们对结果没有任何影响。
首先,抛弃错误。现在您有这些条目及其原始位置
1 1 1 1 1 1
1 2 4 5 7 8
"中间"数字是1(4)。它小于2(寻求值),所以我们抛弃左边的所有东西并重新处理右边。现在我们有了
1 1 1
5 7 8
中间值为1(7)。它小于2,所以我们抛弃左边的所有内容并重新处理右边的内容。现在我们有了
1
8
我们归结为一个条目,这就是答案。如果搜索到的值高于所有其他值,则二进制搜索将始终返回最后一个值。
答案 1 :(得分:4)
逻辑是这样的:
B1:B12="meat"
返回一个布尔数组,TRUE表示“meat”,否则返回FALSE 基本上,这个shenanigan依赖于未记录的行为来返回所需的结果。