場景:我想數數。在兩個零之間具有負數的子集。這里沒有。負數的子集可以被認為是從海平面下山
考慮一個陣列
a=[0,1,0,-1,-2,-l,0]
這里的0代表海平面。零之間的數字是向上/向下的步驟,并由正/負連續步驟表示。您可以向上/向下移動任何臺階,但在向上/向下移動之前它應該達到海平面
如果你考慮
0,1,0那么這意味著你從海平面移動到上坡然后再次移動到海平面
0, 1, 0
相似地
從海平面到下移一步,下移第二步,再上移一步,再到海平面
0, -1, -2, -1, 0
現在考慮一個例子。
a=[0,1,0,-1,-2,-1,0]
subset #1 = [0,1]
subset #2 = [0,-1,-2,-1,0]
輸出:(1一次在海平面以下旅行)
考慮另一個例子
b = [0,1,2,1,0,-1,-2,-1,0,1,2,1,0,-1,0]
subset #1 = [0,1,2,1,0] (moving up)
subset #2 = [0,-1,-2,-1,0] (moving down)
subset #3 = [0,1,2,1,0] (moving up)
subset #4 = [0,-1,0] (moving down)
輸出:(2兩次在海平面以下行進)
uj5u.com熱心網友回復:
我想知道您是否有理由不能只計算零后跟負數的次數;就像是:
def count_below(arr)
count = 0
arr.each_index do |i|
count = 1 if arr[i] == 0 && (arr[i 1] || 0) < 0
end
count
end
irb(main):039:0> count_below([0,1,0,-1,-2,-1,0])
=> 1
irb(main):040:0> count_below([0,1,2,1,0,-1,-2,-1,0,1,2,1,0,-1,0])
=> 2
uj5u.com熱心網友回復:
選項 1:產生所需的“輸出”(低于“海平面”的次數)
假設:
- 我們從海平面或以上開始。
建議的解決方案:
b = [0,1,2,1,0,-1,-2,-1,0,1,2,1,0,-1,0]
b.each_cons(2).count {|a,b| !a.negative? && b.negative? }
步驟:
- 創建一個
Enumerator連續 2 個元素 (b.each_cons(2)) - 每次第一個元素不是負數,第二個元素是負數時計數 (
count {|a,b| !a.negative? && b.negative? })
選項 2:要在您的問題中生成切片,以下應該有效
假設:
- 我們總是從海平面開始 (
0) - 上升或下降時必須觸摸海平面(例如
[0,1,-1]被視為無效輸入) - 第一個例子不正確,應該是
[[0,1,0],[0,-1,-2,-1,0]]
建議的解決方案:
b.each_cons(2).with_object([]) do |(a,b),obj|
obj << [a] if a.zero?
obj.last << b
end
#=> [[0, 1, 2, 1, 0], [0, -1, -2, -1, 0], [0, 1, 2, 1, 0], [0, -1, 0]]
步驟:
- 創建一個
Enumerator連續 2 個元素 (b.each_cons(2)) - 使用累加器
Array(with_object([]))進行迭代 - 每次第一個元素
0插入一個新的子Array(obj << [a] if a.zero?) - 將第二個元素插入當前(最后一個)子
Array(obj.last << b) with_object將回傳累加器Array作為結果
您可以鏈接方法以獲得與選項 1 相同的結果(例如count {|a| a.any?(&:negative)})
uj5u.com熱心網友回復:
我的解決方案假設您希望計算以零開頭和結尾的子陣列的數量,并且從初始零單調減少到最小(負)值,然后單調增加到最終零。
def count_em(arr)
arr.flat_map.with_index { |e,i| (e.zero? && i > 0 && i < arr.size-1) ? [0,0] : [e] }
.slice_when { |*pair| pair == [0,0] }
.count { |a| downhill?(a) }
end
def downhill?(arr)
return false if arr[1] > 0
imin = arr.each_index.min_by { |i| arr[i] }
return false unless decreasing?(arr[0..imin])
decreasing?(arr[imin..-1].reverse)
end
def decreasing?(arr)
arr.each_cons(2).all? { |e,f| f < e }
end
count_em [0, 1, 0, -1, -2, -1, 0]
#=> 1
count_em [0, 1, 2, 1, 0, -1, -2, -1, 0, 1, 2, 1, 0, -1, 0]
#=> 2
count_em [0, -2, -1, -2, 0]
#=> 0
count_em [0, -1, -2, 1, 0]
#=> 0
最后兩個例子反映了我對這個問題的理解。
計算如下。
arr = [0, 1, 2, 1, 0, -1, -2, -1, 0, 1, 2, 1, 0, -1, 0]
使用Enumerable#flat_map和Enumerator#with_index將零插入到arr每個零之后但第一個和最后一個的副本中。
a = arr.flat_map.with_index { |e,i| (e.zero? && i > 0 && i < arr.size-1) ? [0,0] : [e] }
#=> [0, 1, 2, 1, 0, 0, -1, -2, -1, 0, 0, 1, 2, 1, 0, 0, -1, 0]
我們現在可以使用Enumerable#slice_when來獲取以零開頭和結尾的每個子陣列。
enum = a.slice_when { |*pair| pair == [0,0] }
#=> #<Enumerator: #<Enumerator::Generator:0x00007fa9fd970f28>:each>
我們可以通過將此列舉器轉換為陣列來查看將生成的元素。
enum.to_a
#=> [[0, 1, 2, 1, 0], [0, -1, -2, -1, 0], [0, 1, 2, 1, 0], [0, -1, 0]]
最后,使用Enumerable#countenum計算“下坡”生成的四個陣列的數量。
enum.count { |a| downhill?(a) }
#=> 2
這是因為
downhill? [0, 1, 2, 1, 0] #=> false
downhill? [0, -1, -2, -1, 0] #=> true
downhill? [0, 1, 2, 1, 0] #=> false
downhill? [0, -1, 0] #=> true
要查看如何downhill?作業,讓
arr = [0, -1, -2, -1, 0]
然后
arr[1] > 0
#=> -1 > 0 => false, so do not return
imin = arr.each_index.min_by { |i| arr[i] }
#=> 2
decreasing?(arr[0..imin])
#=> decreasing? [0, -1, -2] => false, so do not return
decreasing?(arr[imin..-1].reverse)
#=> decreasing? [-2, -1, 0].reverse => [0, -1, -2]
# decreasing? [0, -1, -2] => true
現在讓我們看看由 執行的計算decreasing?。認為
arr = [0, -1, -2]
我們看到
enum = arr.each_cons(2)
#=> #<Enumerator: [0, -1, -2]:each_cons(2)>
enum生成以下陣列:
enum.to_a
#=> [[0, -1], [-1, -2]]
因此
arr.each_cons(2).all? { |e,f| f < e }
#=> true
因為-1 < 0 #=> true和-2 < -1 #=> true。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/472676.html
