【问题标题】:Find if n exists as a sum of any 2 numbers in the given array查找 n 是否作为给定数组中任意 2 个数字的总和存在
【发布时间】:2013-10-29 02:24:03
【问题描述】:

我试图找出 n 是否作为传递数组中任意两个数字的总和存在,如果返回 true 否则 false,我的代码的问题是 inject 没有像我一样迭代想要它。我做错了什么?

def sum_to_n?(array,n)
  array.each do |i|
    array.inject(i) do |memo,var|
      if memo + var == n
        return true
      else
        return false
      end
    end
  end
end

puts sum_to_n?([1,2,3,4,5],9)

【问题讨论】:

  • 会发生什么,您希望发生什么?
  • return false 如果 memo + var != n 立即。这意味着除非第一个匹配项总和为 n,否则您的方法总是返回 false。此外,您的注入循环不会像您认为的那样做。
  • @AndrewMarshall 它没有迭代,我希望它修改以便它可以迭代
  • @HunterMcMillen 是的,似乎是这样

标签: ruby each inject


【解决方案1】:

这是一种方法:

def sum_to_n?(a,n)
  !!a.find{|e| a.include?(n-e)}
end
a = [1,2,3,4,5]
sum_to_n?(a,9) # => true
sum_to_n?(a,11) # => false

如果你想获得这 2 个元素:

def sum_to_n?(a,n)
  num=a.find{|e| a.include?(n-e)}
  unless num
    puts "not exist"
  else
    p [n-num,num]
  end
end
a = [1,2,3,4,5]
sum_to_n?(a,9)
# >> [5, 4]
sum_to_n?(a,11)
# >> not exist

逻辑

Enumerable#find 方法每次迭代传递一个数组元素。现在对于任何迭代,假设我有一个元素 e,我从 n 中减去它。现在我只是测试(n-e) 是否存在于源数组中。如果我找到匹配#find 将停止查找,并立即返回e。如果没有找到,那么它将进行下一次迭代。如果#find 完成了它的迭代,但没有找到(n-e),根据文档它将返回nil

【讨论】:

  • 简洁明了!!
  • @HunterMcMillen 我按照你说的解释了.. :)
  • Arup,或许在开头加一行:(return a.select {|e| e==0}.size > 1) if n == 0
【解决方案2】:

这个问题已经回答了,但我认为这种方法更具可读性:

def sum_to_n?(a,n)
  a.combination(2).find{|x,y| x+y==n}
end

a = [1,2,3,4,5]
p sum_to_n?(a,9)  # => [4, 5]
p sum_to_n?(a,11) # => nil

【讨论】:

    【解决方案3】:

    从来没有一个做事简单的人:

    n = 14
    a = [1,3,5,9,13,3,18]
    if n==0
      a.select {|x| x == 0}.size > 1
    else
      a.map {|x| 2*x - n}.uniq.group_by(&:abs).values.map(&:size).max > 1 # => true
    end
    
    • 对于 n != 0,将值加倍并减去 n => [-12, -8, -4, 4, 12, -8, 22]。我们现在正在寻找总和为零的对。
    • uniq => [-12, -8, -4, 4, 12, 22] 如果a 有重复项(两个 3)。如果没有 uniq,我们下一步就会遇到麻烦。
    • 按绝对值分组 => {12=>[-12, 12], 8=>[-8], 4=>[-4, 4], 22=>[22]}。大小为 2 的哈希值对应于总和为 n 的对(1+13 => [-12,-12] 和 5+9 => [-4, 4])。
    • 选择哈希值,映射到 .size => [2, 1, 2, 1],然后查看 [2, 1, 2, 1].max > 1。

    【讨论】:

      【解决方案4】:
      arr = [1, 2,3,4,5,6,7]
      
      num = 7  (given number for 2 element combination)
      

      下面的程序只会返回单个组合

      arr.uniq.combination(2).detect {|a, b| a + b == num}
      
      => [2, 5]
      

      下面的程序将返回所有可能的组合

      arr.uniq.combination(2).find_all {|a, b| a +b == num}
      
      => [[2, 5], [3, 4]]
      

      【讨论】:

        【解决方案5】:

        红宝石

        此代码将拒绝空数组并返回带有值的正确数组。

        def find_sequence(val, num)
        b = val.length (0..b - 1).map {|n| val.uniq.combination(n).each.find_all {|value| value.reduce(:+) == num}}.reject(&:empty?)
        结束

        val = [-10, 1, -1, 2, 0] num = 2

        输出将是 [[2],[2,0],[-1,1,2],[-1,1,2,0]]

        【讨论】:

          猜你喜欢
          • 2011-12-28
          • 2020-06-30
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-06-06
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多