在以下程式中,回圈似乎在運行 2 次后停止,而不是預期的 3 次。的期望值sum_of_sums為 35,但這里是 23。
ary = [1,2,3,4]
sum_of_sums = 0
ary.each do # => [1, 2, 3, 4]
n=ary.shift # => 1, 2
sum_of_products = ary.reduce(0) do |memo,e| # => [2, 3, 4], [3, 4]
memo (n*e) # => 2, 5, 9, 6, 14
end
sum_of_sums = sum_of_products # => 9, 23
end
sum_of_sums # => 23
它按預期與 [1,2,3] 一起作業:
ary = [1,2,3]
sum_of_sums = 0
ary.each do # => [1, 2, 3]
n=ary.shift # => 1, 2
sum_of_products = ary.reduce(0) do |memo,e| # => [2, 3], [3]
memo (n*e) # => 2, 5, 6
end
sum_of_sums = sum_of_products # => 5, 11
end
sum_of_sums # => 11
我正在嘗試撰寫一個程式,對于集合 [a,b,c,d],計算
ab ac ad bc bd cd. 除了舉例,我不知道如何表達這種模式。是的,我可以通過分解條款更明確或更輕松地做到這一點,但我想知道為什么這個回圈不起作用!
編輯:謝謝大家...看來問題是#shift在#each回圈中修改了陣列。我最終成功了:
ary = [1,2,3,4]
sum = 0
until ary.count==1 do
sum = ary.shift * ary.sum
end
sum
uj5u.com熱心網友回復:
考慮到您的問題已得到解答,我想建議一種更有效的計算方法。請注意
(a b c)**2 = a**2 b**2 c**2 2*(ab ac bc)
所以
ab ac bc = ((a b c)**2 - (a**2 b**2 c**2))/2
因此我們可以寫
def sum_of_cross_terms(arr)
((arr.sum)**2 - arr.reduce(0) { |t,n| t n**2 })/2
end
sum_of_cross_terms([1, 2, 3])
#=> 11
sum_of_cross_terms([1, 2, 3, 4])
#=> 35
我們看到這個計算的計算復雜度是 O(· arr.size),而蠻力方法是 O(· (arr.size)**2)。后者的一個例子是
def sum_of_cross_terms(arr)
arr.combination(2).sum { |a,b| a*b }
end
uj5u.com熱心網友回復:
就像 spickermann 所說的那樣,您正在修改正在迭代的陣列,同時迭代它。這會產生意想不到的結果。
如果您想使用,shift則使用不受移動(修改)陣列影響的東西構造回圈。
(ary.size-1).times.map { ary.shift * ary.sum }.sum
如果不修改陣列,它會變得更加冗長:
(ary.size-1).times.map { |i| ary[i] * ary.drop(i 1).sum }.sum
您還可以在迭代之前進行復制:
ary.dup.map { ary.shift * ary.sum }.sum
或使用with_index:
ary.map.with_index { |n, i| n * ary.drop(i 1).sum }.sum
還有很多其他方法可以做到這一點,但希望這能給你一些想法。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/359992.html
標籤:红宝石
