2014-03-24 29 views
1

我必须做n个数组的乘法。数组乘法 - 什么是最好的算法?

实施例:

  • 输入= [ “一”, “B”, “C”] * [ “1”, “2”] * [ “&”, “(”, “$” ]
  • output = [“a1 &”,“a1(”,“a1 $”,“a2 &”,“a2(”,“a2 $”,“b1 &”,“b1(”,“b1 $ “ ”B2 &“, ”B2(“,” B2 $, “C1 &,” C1(“C1 $, “C2 &”, “C(”, “C $”]

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

# 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 

我确定有一个最好的方法来做到这一点,但我没有找到它。我曾尝试过使用产品或平板功能而没有成功。

有人看到最佳解决方案?

感谢您的帮助。

埃里克

回答

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

虽然这可能是最好的解决方案,但重写stdlib方法至少不保留其原始行为并不是一个好主意。 – toro2k

+0

@ toro2k这正是OP想要的。你应该评论OP的问题。 – sawa

+0

@sawa - 谢谢你,这正是我想要的 – elhostis

3

你可以使用的最好的算法由Array#product方法来实现:

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

更新
更安全的替代,我的第一个解决方案提出了一个NoMethodError如果data是emtpy:

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

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