如何在Ruby中循环循环

时间:2014-03-29 11:48:43

标签: ruby algorithm

我试图循环数字1到1000,使得我拥有所有可能的对,例如1和1,1和2,1和3,......,但也有2和1,2和2,2和3等等,等等。

在这种情况下,我有一个条件(amicable_pair),如果两个数字是友好对,则返回true。我想检查从1到n的所有数字,并将所有友好对添加到总total。如果它是友好对的一部分,则第一个值将被添加到总数中(不是该对的第二个值,因为我们将在循环的后面找到它)。为此,我编写了以下“类似Java”的代码:

def add_amicable_pairs(n)
  amicable_values = []
  for i in 1..n
    for j in 1..n
      if (amicable_pair?(i,j)) 
        amicable_values.push(i)
        puts "added #{i} from amicable pair #{i}, #{j}"
      end
    end
  end
  return amicable_values.inject(:+)
end

这有两个问题:(1)真的慢。 (2)在Ruby中,你不应该使用for循环。

这就是为什么我想知道如何以更快,更类似Ruby的方式实现这一目标。任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:2)

您的代码具有O(n^2)运行时,因此如果n变得适度大,那么它自然会很慢。如果搜索空间很大,暴力算法总是慢。为了避免这种情况,有没有什么方法可以直接找到“友好对”而不是循环遍历所有可能的组合并逐个检查?

至于如何以更优雅的方式编写循环,我可能会将您的代码重写为:

(1..n).to_a.product((1..n).to_a).select { |a,b| amicable_pair?(a,b) }.reduce(0, &:+)

答案 1 :(得分:2)

(1..1000).to_a.repeated_permutation(2).select{|pair| amicable_pair?(*pair)}
.map(&:first).inject(:+)