For a given array, I want to compute products always leaving one value out. For example, for input [1, 2, 3, 4]
I want output [2*3*4, 1*3*4, 1*2*4, 1*2*3]
, i.e., [24, 12, 8, 6]
.
对于一个给定的数组,我想要计算的乘积总是只留下一个值。例如,对于输入[1,2,3,4],我希望输出[2*3*4,1*3*4,1*2*4,1*2* 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])
As I track the iteration and array, I get the following results that I do not understand:
当我跟踪迭代和数组时,我得到了以下我不理解的结果:
0
[1, 2, 3, 4]
1
[1, 2, 3, 4]
2
[1, 1, 3, 4]
3
[1, 1, 1, 4]
Shouldn't the array be assigned the duplicate values at the end of each while loop iteration?
数组不应该在每次while循环迭代结束时分配重复值吗?
3 个解决方案
#1
5
There's a lot going on in this code for what should be a simple problem. One of the strengths of Ruby is being able to express a simple solution to this exact problem. I think what you're trying to do comes out as:
在这段代码中有很多问题应该是一个简单的问题。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
It's rare to see conventional for
loops, use of iterator-like variables and such in Ruby because there's a wealth of tools in the Enumerable library that makes them mostly obsolete.
在Ruby中很少看到常规的循环、类迭代变量的使用等等,因为在可枚举库中有大量的工具使它们基本过时。
The key here is to use tools like map
whenever possible in preference to dup
and some hammering around with the data using index variables. The map
function is key for when you need a 1:1 "mapping" of the original data into an array of identical length where you get to decide how to handle each element individually.
这里的关键是在可能的情况下使用像map这样的工具,并且使用索引变量来处理数据。map函数对于您需要将原始数据1:1“映射”到相同长度的数组时非常关键,您可以在该数组中决定如何分别处理每个元素。
This code produces:
这段代码生成:
array_product([ 1, 2, 3 ])
# => [6, 3, 2]
#2
3
Basically you want to find the product of each combination of three numbers.
基本上你想要找到三个数的乘积。
[1,2,3,4].combination(3).map{|c| c.reduce(:*)}
#3
2
Your mistake is that you duplicate the given array only once. For the first index you then work with the given array, and then you set array=array_d
and from then on for all remaining indexes you're working on that duplicate the whole time, writing more and more 1
s into it.
您的错误是只复制给定数组一次。对于第一个索引,然后使用给定的数组,然后设置array=array_d,从那时起,对于所有剩下的索引,您将一直处理这个重复,并在其中写入越来越多的1。
The simplest way to fix it is to use array=array_d.dup
there instead, i.e., just append .dup
there. Then you don't work on the same array over and over again but instead always reset to the original (duplicated) values as you intended.
修复它的最简单的方法是使用array=array_d。dup有相反,即。,就在那里。然后,您不必反复对同一个数组进行处理,而是始终按照您的意愿重置原始(重复)值。
But it's better to just make a duplicate right before the calculation of each product, and use that fresh duplicate to compute the product. So change your inner part to this:
但是最好在每个产品的计算之前复制一份,并使用这个新的副本来计算产品。所以改变你的内在部分:
array_d = array.dup
array_d[itr] = 1
sum << array_d.reduce(:*)
The whole method made rubyish:
整个方法使rubyish:
def array_product(array)
array.each_index.map do |i|
dup = array.dup
dup[i] = 1
dup.reduce(:*)
end
end
By the way, note that you don't need to initialize reduce
with 1
.
顺便说一下,注意不需要用1初始化reduce。
Oh and in case your array doesn't have zeros, you could also just compute the product of all numbers once and then divide it by each number. That's much faster:
哦,如果你的数组没有0,你也可以计算所有数的乘积然后除以每个数。这是快得多:
def array_product(array)
p = array.reduce(:*)
array.map { |x| p / x }
end
#1
5
There's a lot going on in this code for what should be a simple problem. One of the strengths of Ruby is being able to express a simple solution to this exact problem. I think what you're trying to do comes out as:
在这段代码中有很多问题应该是一个简单的问题。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
It's rare to see conventional for
loops, use of iterator-like variables and such in Ruby because there's a wealth of tools in the Enumerable library that makes them mostly obsolete.
在Ruby中很少看到常规的循环、类迭代变量的使用等等,因为在可枚举库中有大量的工具使它们基本过时。
The key here is to use tools like map
whenever possible in preference to dup
and some hammering around with the data using index variables. The map
function is key for when you need a 1:1 "mapping" of the original data into an array of identical length where you get to decide how to handle each element individually.
这里的关键是在可能的情况下使用像map这样的工具,并且使用索引变量来处理数据。map函数对于您需要将原始数据1:1“映射”到相同长度的数组时非常关键,您可以在该数组中决定如何分别处理每个元素。
This code produces:
这段代码生成:
array_product([ 1, 2, 3 ])
# => [6, 3, 2]
#2
3
Basically you want to find the product of each combination of three numbers.
基本上你想要找到三个数的乘积。
[1,2,3,4].combination(3).map{|c| c.reduce(:*)}
#3
2
Your mistake is that you duplicate the given array only once. For the first index you then work with the given array, and then you set array=array_d
and from then on for all remaining indexes you're working on that duplicate the whole time, writing more and more 1
s into it.
您的错误是只复制给定数组一次。对于第一个索引,然后使用给定的数组,然后设置array=array_d,从那时起,对于所有剩下的索引,您将一直处理这个重复,并在其中写入越来越多的1。
The simplest way to fix it is to use array=array_d.dup
there instead, i.e., just append .dup
there. Then you don't work on the same array over and over again but instead always reset to the original (duplicated) values as you intended.
修复它的最简单的方法是使用array=array_d。dup有相反,即。,就在那里。然后,您不必反复对同一个数组进行处理,而是始终按照您的意愿重置原始(重复)值。
But it's better to just make a duplicate right before the calculation of each product, and use that fresh duplicate to compute the product. So change your inner part to this:
但是最好在每个产品的计算之前复制一份,并使用这个新的副本来计算产品。所以改变你的内在部分:
array_d = array.dup
array_d[itr] = 1
sum << array_d.reduce(:*)
The whole method made rubyish:
整个方法使rubyish:
def array_product(array)
array.each_index.map do |i|
dup = array.dup
dup[i] = 1
dup.reduce(:*)
end
end
By the way, note that you don't need to initialize reduce
with 1
.
顺便说一下,注意不需要用1初始化reduce。
Oh and in case your array doesn't have zeros, you could also just compute the product of all numbers once and then divide it by each number. That's much faster:
哦,如果你的数组没有0,你也可以计算所有数的乘积然后除以每个数。这是快得多:
def array_product(array)
p = array.reduce(:*)
array.map { |x| p / x }
end