Ruby中的累积逆数组和

时间:2017-03-02 04:07:45

标签: ruby

我正在计算从每个索引到数组末尾的数组值之和。像这样:

array = [50, 40, 30,20]
array.map.with_index{|x,i| x = array[i..array.length].reduce(:+) }
=> [140, 90, 50, 20]

有没有更清洁,像红宝石般的更有效的方法呢?已经讨论了累积数组和here

5 个答案:

答案 0 :(得分:7)

我定义了一个scanl帮助器来收集reduce的结果:

module Enumerable
    def scanl(initial, sym)
        self.reduce([initial]) { |m, n| m << m[-1].send(sym, n) }[1..-1]
    end
end

scanr向后执行此操作:

def scanr(initial, sym)
    self.reverse_each.scanl(initial, sym).reverse
end

就是这样:

array.scanr(0, :+)

答案 1 :(得分:3)

正如您提到的那样有效,我没有按照 Best case Avg case Worst case LS 1 comparison n/2 comp. n comp BS 1 comparison O(log_n) O(log_n) 方式执行您的代码:它的时间复杂度为map.with_index

反向cumulative_sum可以使用cumulative_sum和2 O(n^2)

完成
reverse

答案 2 :(得分:2)

这是一个棘手的方法:

sum = array.inject(a[-1], &:+)
array.map.with_index { |x, i| sum -= a[i-1] }
=> [140, 90, 50, 20]

答案 3 :(得分:1)

array.each_with_object([array.inject(:+)]){|e, a| a << a.last - e}[0...-1]
# => [140, 90, 50, 20]

答案 4 :(得分:1)

array.reverse_each.with_object([]) { |n,a| a.unshift(n + a.first.to_i) }
  #=> [140, 90, 50, 20]

从数组的最后一个元素开始并向前工作,每个元素和a的第一个元素(要构建的数组,要返回)的总和被推到{{1}的前面}。当a为空时,

a

或者,可以写

a.first.to_i
  #=> [].first.to_i => nil.to_i => 0

使用Array#reverse_each只需要一次通过(a.first || 0)