【发布时间】:2018-03-03 00:21:04
【问题描述】:
我在 R 中编写了一个递归二分搜索函数,它在向量中找到大于给定值的最小元素:
binary_next_biggest <- function(x, vec){
if (length(vec) == 1){
if (x < vec[1]){
return(vec[1])
} else {
return(NA)
}
} else {
mid = ceiling(length(vec)/2)
if (x < vec[mid]){
return(binary_next_biggest(x, vec[1:mid]))
} else {
return(binary_next_biggest(x, vec[mid+1:length(vec)]))
}
}
}
我在 Python 中编写了这个完全相同的函数,没有任何问题(代码如下),但在 R 中它不起作用。
import numpy as np
def binary_next_biggest(x, arr):
if len(arr)==1:
if x < arr[0]:
return arr[0]
else:
return None
else:
mid = int(np.ceil(len(arr)/2)-1)
if x < arr[mid]:
return binary_next_biggest(x, arr[:mid+1])
else:
return binary_next_biggest(x, arr[mid+1:])
通过在 RStudio 中的调试,我发现了它为什么不起作用的机制:在我上面的函数中索引向量会返回一个相同长度的向量,所以如果
vec <- 1:10
并且vec在函数内被索引,
vec[6:10]
传递给 binary_next_biggest() 的新调用的结果向量是
6 7 8 9 10 NA NA NA NA NA
我期望的地方
6 7 8 9 10
这里发生了什么?我知道我可以将它重写为一个迭代更改索引的 while 循环,但我不明白为什么向量索引在我编写的代码中会以这种方式运行。在交互式 R 控制台中,索引的行为符合预期并更改了向量长度,那么为什么它在函数中的行为会有所不同,以及为我正在尝试做的事情建立索引的合适方法是什么?
【问题讨论】:
-
尝试
(mid+1):length(vec)而不是mid+1:length(vec)。 -
啊,做到了。现在我觉得很愚蠢,哈哈,这让我以前也有过。谢谢!
-
@AndreyShabalin 您介意发表您的评论作为答案,以便我选择它并关闭问题吗?
-
当然,会发布一个答案。
-
取决于您的数据是整数还是浮点数,我猜,但
findInterval(vs, DF$v)或findInterval(vs, DF$v) + 1L应该可以找到匹配的位置;然后只需DF$v[res]即可获得价值。
标签: r performance indexing binary-search