对于给定的数组,我想计算总是留下一个值的产品。例如,对于输入[1, 2, 3, 4]
,我想要输出[2*3*4, 1*3*4, 1*2*4, 1*2*3]
,即[24, 12, 8, 6]
。
def array_product(array)
arr_lgth=array.length
array_d=array.dup
sum=[]
itr=0
while itr<(arr_lgth)
p itr
p array
array[itr]=1
sum << array.reduce(1,:*);
array=array_d
itr+=1
end
return sum
end
array_product([1,2,3,4])
当我跟踪迭代和数组时,我得到以下不明白的结果:
0
[1, 2, 3, 4]
1
[1, 2, 3, 4]
2
[1, 1, 3, 4]
3
[1, 1, 1, 4]
在每个while循环迭代结束时,不应该为数组分配重复值吗?
答案 0 :(得分:5)
这段代码中有很多内容应该是一个简单的问题。 Ruby的优势之一是能够为这个确切的问题表达一个简单的解决方案。我认为你要做的事情是:
def array_product(array)
# Convert each index in the array...
array.each_index.map do |i|
# ...into a copy of the array with that index set as 1...
array.each_with_index.map do |a, j|
i == j ? 1 : a
end.reduce(1, :*) # ...multiplied together.
end
end
很少见到传统的for
循环,在Ruby中使用类似迭代器的变量,因为Enumerable库中有大量工具使它们大多数过时。
这里的关键是尽可能使用像map
这样的工具而不是dup
,并且使用索引变量来处理数据。当您需要1:1&#34;映射&#34;时,map
功能是关键。将原始数据放入一个相同长度的数组中,您可以决定如何单独处理每个元素。
此代码生成:
array_product([ 1, 2, 3 ])
# => [6, 3, 2]
答案 1 :(得分:3)
基本上你想找到三个数字的每个组合的乘积。
[1,2,3,4].combination(3).map{|c| c.reduce(:*)}
答案 2 :(得分:2)
您的错误是您只复制一次给定的数组。对于第一个索引,然后使用给定的数组,然后设置array=array_d
,然后在上设置所有剩余的索引,您正在处理重复的在整个过程中,越来越多地将1
写入其中。
解决此问题的最简单方法是在其中使用array=array_d.dup
,即只在其中附加.dup
。然后你不能一遍又一遍地在同一个数组上工作,而是总是按照你的意愿重置为原始(重复)值。
但是,在计算每个产品之前,只需重复,并使用新的副本来计算产品,这样做会更好。所以改变你的内心部分:
array_d = array.dup
array_d[itr] = 1
sum << array_d.reduce(:*)
整个方法制作了红宝石:
def array_product(array)
array.each_index.map do |i|
dup = array.dup
dup[i] = 1
dup.reduce(:*)
end
end
请注意,您不需要使用reduce
初始化1
。
哦,如果您的阵列没有零,您也可以只计算所有数字的产品,然后将其除以每个数字。那要快得多:
def array_product(array)
p = array.reduce(:*)
array.map { |x| p / x }
end