【问题标题】:How to create all possible combinations with two arrays如何使用两个数组创建所有可能的组合
【发布时间】:2014-01-02 18:59:22
【问题描述】:

我现在的问题是找到 a**b a,b

a = []
b = []
(1..100).map {|n| a << n}
(1..100).map {|n| b << n}

我还决定做一个 sum_of_digits 方法:

class Integer
  def sum_of_digits
  self.to_s.split("").map {|p| p.to_i}.reduce(:+)
  end
end

所以现在我需要构造一个包含 a**b 的所有组合的数组 我怎么能这样做? 谢谢!

【问题讨论】:

  • 我想建议澄清一下(假设我正确理解了这个问题):确定所有整数对 i 和 j 中数字 i**j 的数字总和的最大值, 1 sum_of_digits 方法中,不需要 self.,因为接收者是 self

标签: ruby


【解决方案1】:

您可以使用Array#product 方法:

a = [1,2,3]
b = [4,5,6]

a.product(b)
# => [[1, 4], [1, 5], [1, 6], [2, 4], ...]

a.product(b).map { |x, y| x ** y }
# => [1, 1, 1, 16, 32, 64, 81, 243, 729]

那么,给定你的Integer#sum_of_digits 定义:

a.product(b).map { |x, y| x ** y }.max_by(&:sum_of_digits)
# => 729

更新:计算数字的最大数字和 (a ** b),其中 a、b 是小于或等于 100 的自然数,我会这样做:

Array(1..100)
  .repeated_permutation(2)
  .map { |a, b| (a ** b).sum_of_digits }
  .max

【讨论】:

  • 那么你会使用什么代码呢?问题正是:googol (10100) 是一个巨大的数字:一个后面跟着一百个零; 100100 几乎是难以想象的大:一个后面跟着两百个零。尽管它们的大小,每个数字中的数字和只有 1。考虑自然数形式 a**b,其中 a, b
  • @user3127905 我已经更新了答案,希望我现在就明白了。请编辑您的问题以澄清 Cary Swoveland 所指出的。
【解决方案2】:

跳过数组并在范围上使用repeated_permutation 帮助器来获取枚举器:

(1..100).to_a.repeated_permutation(2)

在枚举器上调用to_a 将为您提供所有排列的数组。但是,您可以直接对枚举器进行操作以提高工作效率:

(1..100).to_a.repeated_permutation(2).reduce([0]) do |m,(a,b)| 
  r = (a**b).sum_of_digits
  r > m.last ? [[a,b],r] : m
end
=> [[99, 95], 972]

虽然您可以致电map,然后找到max。这将需要实际上一次保存所有排列结果。在枚举器上调用 reduce 只需要在任何给定时间保持一个排列和先前排列的结果。

【讨论】:

  • 您是在说“使用permutation(2)”,因为您没有提及a**b 或最大化数字总和?
  • @CarySwoveland - 你说得对,我误解了 OP 想要如何使用这些排列。已更新。
【解决方案3】:

编辑:@PinnyM 正确地指出我应该使用 Array#repeated_permutation 而不是 Array#permutation,因为后者不包括对 [i,i]。为了多样性,我没有进行更正,而是将a.permutation(2).to_a替换为a.permutation(2).to_a + a.zip(a)

  a = (1..100).to_a
  (a.permutation(2).to_a + a.zip(a)).map {|i,j| (i ** j).sum_of_digits}.max
    # => 972

获胜者是:

  (a.permutation(2).to_a + a.zip(a)).map \
    {|i,j| [i, j, (i ** j).sum_of_digits]}.max_by(&:last)
    # => [99, 95, 972] (99**95).sum_of_digits # => 972

如果是i &lt;= 3,而不是i &lt;= 100,则执行以下步骤:

a = (1..3).to_a # => [1,2,3]
b = a.permutation(2) # => #<Enumerator: [1, 2, 3]:permutation(2)>
c = b.to_a # => [[1, 2], [1, 3], [2, 1], [2, 3], [3, 1], [3, 2]] 
d = a.zip(a) # => [[1, 1], [2, 2], [3, 3]]
e = c + d # => [[1,2], [1,3], [2,1], [2,3], [3,1], [3,2], [1,1], [2,2], [3,3]] 
f = e.map {|i,j| (i ** j).sum_of_digits} # => [1, 1, 2, 8, 3, 9, 1, 4, 9]
f.max # => 9

在 Ruby 2.0 中,您可以通过将 class Integer 替换为 refine Integer do 来将 sum_of_digits 方法的使用限制在当前上下文(例如类)中。如果您认为您可能想在其他地方使用该方法,您可以将它放在一个模块中,并在需要的地方 include 模块。

【讨论】:

  • 实际上,正如其他人所提到的,您需要使用repeated_permutation(而不是permutation),因为ij 可能是同一个数字。
  • 谢谢,@PinnyM。我修好了。
【解决方案4】:
combinations = []
a.each do |n1|
  b.each { |n2| combinations << n1**n2 }
end

编辑:
您将所有值加倍。这就是您要搜索的内容吗?

【讨论】:

    猜你喜欢
    • 2020-02-29
    • 1970-01-01
    • 2021-10-02
    • 2019-05-15
    • 1970-01-01
    • 1970-01-01
    • 2012-02-14
    • 2022-09-28
    相关资源
    最近更新 更多