![](/img/trans.png)
[英]Can someone explain why I get this error message on localhost:3000?
[英]Can someone please explain why this doesn't work? sometimes I get nil
所以我正在解決這些練習問題,也許有更好的方法來做到這一點,但這就是我得到的。 我很困惑為什么這只有時似乎有效......
def nearest_larger(arr, idx)
bigs = []
arr.each do |num|
if num > arr[idx]
bigs << num
end
end
sorted = bigs.sort
if sorted.length > 1
sorted = sorted[0]
end
return arr.index(sorted)
end
puts nearest_larger([2, 3, 4, 8], 2) #DOES NOT WORK
puts nearest_larger([2, 3, 4, 8], 2) #DOES WORK
puts nearest_larger([8, 8, 4, 2], 2) #ALSO WORKS... why?!!!
我不清楚這個函數到底應該做什么,因為我不知道你在做什么,但我看到的最明顯的問題是你有時檢查另一個數組的數組,有時檢查它用於實際元素。 特別是可疑塊是if sorted.length > 1; sorted = sorted[0]; end
if sorted.length > 1; sorted = sorted[0]; end
if sorted.length > 1; sorted = sorted[0]; end
。
在您的第一個不起作用的調用中,只有一個數字大於索引2
,即 8。在這種情況下sorted
的長度僅為1
- 因此它不會將其從數組更改為第一項到期到你的 if 語句。
無論如何,第二種情況也不應該起作用。
代碼的稍微修改的工作版本如下。
def nearest_larger(arr, idx)
larger_numbers = []
arr.each do |num|
if num > arr[idx]
larger_numbers << num
end
end
smallest_larger_number = larger_numbers.sort()[0]
return arr.index(smallest_larger_number)
end
較小的版本是這樣的:
def nearest_larger(arr, idx)
arr.index(arr.select {|num| num > arr[idx]}.sort()[0])
end
給定的陣列a
和數組索引i
,假設idxa
是索引數組j
的a
為其中a[j] > a[i]
如果idxa
為空,則返回nil
; 否則問題是在idxa
找到一個索引k
,其中(ki).abs
是最小值。 如果idx
包含多個索引k
其中(ki).abs
是最小值,則可以返回這些索引中的任何一個。
選擇索引並找到最接近的
這是解決問題的一種簡單但不是特別有效的方法。
def nearest_larger(arr, idx)
v = arr[idx]
a = arr.each_index.select { |i| arr[i] > v }
return nil if a.empty?
a.min_by { |i| (i-idx).abs }
end
test = [
[[2, 3, 4, 8], 2],
[[8, 5, 4, 3], 2],
[[8, 3, 4, 2], 2],
[[8, 5, 8, 2], 2]
]
test.each do |arr, idx|
i = nearest_larger(arr, idx)
puts "#{arr} idx = #{idx}: closest idx = #{i.nil? ? "nil" : i}"
end
[2, 3, 4, 8] idx = 2: closest idx = 3
[8, 5, 4, 3] idx = 2: closest idx = 1
[8, 3, 4, 2] idx = 2: closest idx = 0
[8, 5, 8, 2] idx = 2: closest idx = nil
讓我們檢查這些arr
和idx
值的步驟:
arr = [8, 5, 4, 3]
idx = 2
v = arr[idx]
#=> 4
e = arr.each_index
#=> #<Enumerator: [8, 5, 4, 3]:each_index>
正如您看到的Array#each_index方法,當在arr
調用時返回一個枚舉器。 將其視為產生價值的機器。 我們可以將枚舉器轉換為數組以查看它們將生成什么值:
e.to_a
#=> [0, 1, 2, 3]
繼續,
a = e.select { |i| arr[i] > v }
#=> [0, 1]
e
將元素傳遞給Enumerable#select ,后者又傳遞給塊,將塊變量i
分配給它們的值。 其實我們可以寫
ee = e.select
#=> #<Enumerator: #<Enumerator: [8, 5, 4, 3]:each_index>:select>
ee.to_a
#=> [0, 1, 2, 3]
a = ee.each { |i| arr[i] > v }
#=> [0, 1]
ee
可以被認為是一個復合枚舉器。 如果最后一點令人困惑,請暫時忘記它。
繼續,
return nil if a.empty?
a
不為空,所以我們不返回。 最后一步如下。
a.min_by { |i| (i-idx).abs }
#=> 1
請注意,我可以用arr.size.times
(參見Integer#times )或0.up_to(arr.size-1)
(參見Integer#upto )替換arr.each_index
。
檢查任一側然后移出一個直到找到更大的值
我們可以以增加復雜性為代價來提高效率。 事實上,下面的代碼不是很像 Ruby 並且 imo 相當沒有吸引力。
def nearest_larger(arr, idx)
v = arr[idx]
last = arr.size-1
iup, idn = idx + 1, idx - 1
while iup <= last || idn >= 0
if iup <= last
return iup if arr[iup] > v
iup += 1
end
if idn >= 0
return idn if arr[idn] > v
idn -= 1
end
end
nil
end
test.each do |arr, idx|
i = nearest_larger(arr, idx)
puts "#{arr} idx = #{idx}: closest idx = #{i.nil? ? "nil" : i}"
end
[2, 3, 4, 8] idx = 2: closest idx = 3
[8, 5, 4, 3] idx = 2: closest idx = 1
[8, 3, 4, 2] idx = 2: closest idx = 0
[8, 5, 8, 2] idx = 2: closest idx = nil
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.