IT虾米网

ruby之对数组求和

mfryf 2024年01月13日 编程语言 159 0

下面的代码在 Ruby 1.8/1.9 上通过了测试,但是当我运行 these tests 时在 Ruby 1.9.2 上,我没有收到 Array#sum 的方法错误。例如,

NoMethodError: undefined method `sum' for [3.2, 3.0, 1.5, 0.73, 0.47, 0.23]:Array 

我遇到了 inject(:+),但是当我试图用 sum 替换它时,它产生了其他问题。有两种使用sum 的方法,time_requiredbalance_queues。在第二种方法中,将其处理成旧代码 q1.sum - q2.sum 很复杂。尽可能多的细节/解释会有所帮助。

class FairDistribution 
  def initialize(jobs, num_of_queues) 
    @queues = [ jobs.sort.reverse ] 
    (num_of_queues - 1).times { @queues << [] } 
 
    # Balance the queues until they are perfectly balanced 
    while !balance_all_queues do; end 
  end 
 
  # Time required for all queues processing 
  def time_required 
    @queues.map { |q| q.sum }.max                      #SUM 
  end 
 
  # The actual distribution of jobs across the queues 
  def distribution 
    @queues 
  end 
 
  private 
 
  # Runs through all queues and balances them against each other. 
  # Makes one pass only and returns FALSE if there was nothing changed 
  # during the pass. 
  def balance_all_queues 
    updated = false 
 
    @queues.each_with_index do |q1, qi1| 
      (qi1+1 ... @queues.size).each do |qi2| 
        res = balance_queues(q1, @queues[qi2]) 
        updated ||= res 
      end 
    end 
 
    return !updated 
  end 
 
  # Balances the two queues between themselves by finding the best possible 
  # swap of jobs between them. If there's nothing to be improved, returns FALSE. 
  def balance_queues(q1, q2) 
    delta =  q1.sum - q2.sum                            #SUM 
    return false if delta == 0 
 
    best_swap       = nil 
    best_swap_delta = delta.abs 
 
    q1.each_combination do |c1| 
      best_swap, best_swap_delta = choose_better_swap(c1, [], delta, best_swap, best_swap_delta) 
 
      q2.each_combination do |c2| 
        best_swap, best_swap_delta = choose_better_swap(c1, c2, delta, best_swap, best_swap_delta) 
      end 
    end 
 
    best_swap.apply(q1, q2) unless best_swap.nil? 
 
    return !best_swap.nil? 
  end 
 
  # Sees if the swap we have at hand is better than our current best 
  # swap and replaces the latest if it is. 
  def choose_better_swap(c1, c2, delta, best_swap, best_swap_delta) 
    unless c1 == c2 
      s = Swap.new(c1, c2, delta) 
      best_swap, best_swap_delta = s, s.delta if s.delta < best_swap_delta  
    end 
 
    return best_swap, best_swap_delta 
  end 
end 

请您参考如下方法:

Enumerable#sum 由 ActiveSupport(Ruby on Rails 的一部分)提供。如果您安装了 active_support gem,您可以通过将其添加到脚本顶部来使用 [].sum:

require 'active_support/core_ext/enumerable' 

尝试使用 .inject(0, :+)。这将导致空数组为“0”,并且可能是您使用 inject 时出现问题的原因。


评论关闭
IT虾米网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!