如何使用ruby中的函数式编程范例重写动态编程中的最大连续子阵列?

时间:2012-08-08 18:05:40

标签: ruby algorithm functional-programming refactoring dynamic-programming

我编写了以下代码来查找具有最大总和的连续子数组,我觉得这很难看:

问题是我内部对这个问题的思考(使用DP)势在必行。如何重构这段代码并使其更具功能性(和干)?关于如何在函数式语言中思考算法的任何建议? (也许应该是一个特殊问题)。

class Object
  def sum(lst)
    lst.reduce(:+)
  end
end

def dp_max_subarray(lst)
  i=0
  s=0
  while i<lst.length
    (i...lst.length).each do |j|
      t = sum lst[i..j]
      if t > s
        s= sum lst[i..j]
        next
      elsif t < 0
        i=j+1
        break
      end
    end
    i+=1
  end
  s
end

2 个答案:

答案 0 :(得分:2)

查看here以获取O(n)Python解决方案。将其转换为功能性Ruby非常简单:

def max_subarray(xs)
  xs.inject([0, 0]) do |(max_so_far, max_up_to_here), x|
    new_max_up_to_here = [max_up_to_here + x, 0].max
    new_max_so_far = [max_so_far, new_max_up_to_here].max
    [new_max_so_far, new_max_up_to_here]
  end.first
end

xs = [31, -41, 59, 26, -53, 58, 97, -93, -23, 84]
max_subarray(xs) #=> 187

答案 1 :(得分:2)

我把它变成了一个单行(虽然效率不高且很难读):

(0...arr.length).map{|start| (1..(arr.length-start)).map{|length| arr.slice(start, length).inject(:+)}.max}.max