如何在Ruby的循环迭代中刷新数组?

问题描述 投票:2回答:3

对于给定的数组,我想计算总是留下一个值的产品。例如,对于输入[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循环迭代结束时为数组分配重复值吗?

arrays ruby
3个回答
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“映射”到相同长度的数组时,map函数是关键,您可以决定如何单独处理每个元素。

此代码生成:

array_product([ 1, 2, 3 ])
# => [6, 3, 2]

3
投票

基本上你想找到三个数字的每个组合的乘积。

[1,2,3,4].combination(3).map{|c| c.reduce(:*)}

2
投票

你的错误是你只复制一次给定的数组。对于第一个索引,然后使用给定的数组,然后设置array=array_d,然后为你正在处理的所有剩余索引设置重复的全部时间,将更多和更多的1s写入其中。

修复它的最简单方法是在那里使用array=array_d.dup,即只需在那里附加.dup。然后,您不会反复使用同一个数组,而是始终按照您的意图重置为原始(重复)值。

但最好在计算每个产品之前立即复制,并使用新的副本来计算产品。所以改变你的内心部分:

    array_d = array.dup 
    array_d[itr] = 1
    sum << array_d.reduce(:*)

整个方法做了rubyish:

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
© www.soinside.com 2019 - 2024. All rights reserved.