0

我不得不使用类似的东西

arr = [10, 20, 50, 80, 110]
(arr.bsearch_index{|a| a >= 50} || arr.length) - 1      # => 1
(arr.bsearch_index{|a| a >= 2000} || arr.length) - 1    # => 4

返回值-1意味着没有这样的索引。如果数字可以是浮动的怎么办,所以你不能寻找49when nis 50。现在的代码有点乱。有没有更优雅的方法来做到这一点?

(也许这就是bsearch_index()它的方式:nil在找不到时返回......所以我们只需要使用bsearch(){ } || arr.length将其转换回严格的数字 - 这就是它的方式。bsearch_index要么只返回数字,要么它可以返回nil作为设计决策,它选择了返回nil。但我不确定我们是否只需要使用上面的代码。也许find-any模式bsearch_index或某种方式可以做到并且更优雅。)

PS使用 reverse() 操作或否定每个元素或某物可能会很有趣,但由于这些是 O(n),它违背了使用二进制搜索使用O(lg n)解决方案的目的,我们可以做一个线性搜索。

4

2 回答 2

0

不完全清楚,但我猜对于排序的数组:

arr.bsearch_index{ |a| a >= n }.then { |i| i ? i - 1 : -1}

或者,由于nil.to_i #=> 0

arr.bsearch_index{ |a| a >= n }.to_i - 1

# n = 49 #=> 1
# n = 50 #=> 1
# n = 51 #=> 2
# n = 111 #=> -1
于 2019-08-30T11:41:34.593 回答
0

In order to express "less than" directly (i.e. via <), you have to reverse the array:

rindex = arr.reverse.bsearch_index { |a| a < 50 }
#=> 4

To un-reverse the index:

arr.size - rindex - 1
#=> 1

In one line:

arr.reverse.bsearch_index { |a| a < 50 }.yield_self { |i| arr.size - i - 1 if i }

The the modifier-if handles i being nil, e.g. a < 10


Or simply use a descending array in the first place:

arr = [110, 80, 50, 20, 10]
arr.bsearch_index { |a| a < 50 }   #=> 3
arr.bsearch_index { |a| a < 2000 } #=> 0
于 2019-08-30T11:51:06.053 回答