数组乘法 - 什么是最好的算法?

时间:2014-03-24 10:15:54

标签: ruby

我必须将n个数组相乘。

示例:

  • input = [“a”,“b”,“c”] * [“1”,“2”] * [“&”,“(”,“$”]
  • output = [“a1&”,“a1(”,“a1 $”,“a2&”,“a2(”,“a2 $”,“b1&”,“b1(”,“b1 $” ,“b2&”,“b2(”,“b2 $,”c1&,“c1(,”c1 $,“c2&”,“c2(”,“c2 $”]

我创建了一个算法来做到这一点,效果很好。

# input
entries = ["$var1$", "$var2$", "$var3$"]
data = [["a", "b", "c"], ["1", "2"], ["&", "(", "$"]]

num_combinaison = 1
data.each { |item| num_combinaison = num_combinaison * item.length  }

result = []
for i in 1..num_combinaison do
  result.push entries.join()
end

num_repetition = num_combinaison
data.each_index do |index|
  item = Array.new(data[index])
  num_repetition = num_repetition / item.length
  for i in 1..num_combinaison do
    result[i-1].gsub!(entries[index], item[0])
    if i % num_repetition == 0
      item.shift
      item = Array.new(data[index]) if item.length == 0
    end
  end
end

我确信有最佳方法可以做到这一点,但我找不到它。我试图使用产品或压扁功能但没有成功。

有人看到了最佳解决方案吗?

感谢您的帮助。

埃里克

2 个答案:

答案 0 :(得分:4)

class Array
  def * other; product(other).map(&:join) end
end

["a", "b", "c"] * ["1", "2"] * ["&", "(", "$"]
# =>
# ["a1&", "a1(", "a1$", "a2&", "a2(", "a2$", "b1&", "b1(", "b1$", "b2&",
# "b2(", "b2$", "c1&", "c1(", "c1$", "c2&", "c2(", "c2$"]

答案 1 :(得分:3)

您可以使用的最佳算法由Array#product方法实现:

data = [["a", "b", "c"], ["1", "2"], ["&", "(", "$"]]
data.first.product(*entries.drop(1)).map(&:join)
# => ["a1&", "a1(", "a1$", "a2&", "a2(", "a2$", ...

<强>更新
一个更安全的替代方案,如果NoMethodError是emtpy,我的第一个解决方案会引发data

data.reduce { |result, ary| result.product(ary).map(&:join) }
# => ["a1&", "a1(", "a1$", "a2&", "a2(", "a2$", ...

[].reduce { |r, a| r.product(a).map(&:join) }
# => nil