检查数组中两个不同数字的和是否等于一个变量数字?

10
在Ruby中,我想要取一个数字数组,选择2个不同的数字,将这2个数字相加,然后判断它们是否等于一个变量x. 我使用的代码如下:

在Ruby中,我想要取一个数字数组,选择2个不同的数字,将这2个数字相加,然后判断它们是否等于一个变量x. 我使用的代码如下:

def arrayIsEqual? (numArray, x)
  return true if numArray.sample + numArray.sample == x
  return false if numArray.empty? || numArray.count == 1
end

例如

numArray = [4,2,7,5]
x = 11

arrayIsEqual(numArray, n) 应该返回 true,因为 4 + 7 = n(11)。

我该怎么做才能让它运行起来呢?

我不希望它是两个随机数字,只要任意两个不同的数字加起来等于 n 就可以了。


3
感谢您在初学者问题中展示出工作的努力,并清晰地表达了问题。欢迎来到 Stack Overflow(堆栈溢出)。 - La-comadreja
1
问题不清楚。你所说的“选择2个不同的数字和一个变量x,然后查看它们是否相等”是什么意思?哪个等于哪个? - sawa
1
-1 并且同意 sawa 的观点。上下文不是很清楚。 - Arup Rakshit
1
你的意思是要检查随机选择的两个数字的总和(这似乎与您的描述相矛盾),还是所有两个数字的总和必须为x,或者某些两个数字的总和必须为x? - sawa
1
你已经有两个关闭投票了,所以最好立即编辑你的问题(即使你已经选择了一个答案)!不要试图在评论中解释你的意思;进行编辑。首先,摆脱随机值的引用,因为它只会让问题更加模糊。保留你的示例,它几乎说明了一切。 - Cary Swoveland
显示剩余3条评论
5个回答

12

看起来你正在尝试查看数组中是否存在任意两个数字相加等于指定的值x。然而,你的代码只是随机选择两个数字并检查它们是否相加。

Ruby有Array#combination方法,该方法可以生成给定长度的所有组合:

def contains_pair_for_sum?(arr, n)
  !!arr.uniq.combination(2).detect { |a, b| a + b == n }
end

需要注意以下几点:

  • 首先,我们按照Ruby的约定命名方法:每个单词都用下划线分隔。结尾的?表示该方法是一个谓词方法,返回一个true或false值。

  • 在方法内部,发生了一些事情。让我们逐个部分来看这一行代码:

    • arr: 我们取得传入的数组。

    • <...>.uniq: 我们只看唯一的元素(因为OP想挑选两个不同的数字)。

    • <...>.combination(2): 我们请求从长度为2的数组中获取所有组合。如果数组是[4, 5, 6],我们将获得[[4, 5], [4, 6], [5, 6]]

    • <...>.detect { |a, b| a + b == n }: 我们寻找第一个加起来等于n的组合。如果找到了一个,那么它就是该方法的结果。否则,我们得到nil

    • !!<...>: 最后,我们取得从detect获得的结果并两次否定它。第一次否定会产生一个布尔值(如果我们获得的值为nil,则为true,否则为任何其他内容,则为false)。第二次否定会产生与第一次否定的真值相同的布尔值。这是Ruby的习惯用法,可以将结果强制转换为truefalse

让我们看看它的实际应用:

array = [4, 5, 9, 7, 8]

contains_pair_for_sum?(array, 11)
# => true (because [4, 7] sums to 11)

contains_pair_for_sum?(array, 17)
# => true (because [9, 8] sums to 17)

contains_pair_for_sum?(array, 100)
# => false (no pair matched)

这两个数字必须不同。是的,我不想选择一个随机数。例如[4,4,7,8]中不能选择4。这看起来很好,但我认为你应该使用arr而不是array,因为它是先定义的。 - user3545961
1
如果你能告诉我在文章本身中不想要随机数,这可能对我有帮助.. :) - Arup Rakshit
1
@user3545961:你想查看是否有任意两个数字的和等于该值吗?还是只想查看任意两个不同的数字 - John Feminella
1
@user3545961: 我更新了。现在它只会检索唯一的数字(这就是 #uniq 的作用)。 - John Feminella
1
@seph 我想要能够演示哪一对实际上是正确答案,这与.detect {}的语义一致。 - John Feminella
显示剩余3条评论

1

我理解您的问题是“我的数组中是否有任何一对数字等于x”,如果是这种情况,那么以下代码可以满足您的需求:

def has_pair_equal?(num_array, x)
  (0..num_array.length-1).any? do |i| 
    num_array[i+1..-1].any? { |n| n + num_array[i] == x }
  end
end

这个程序检查数组中所有数字对的和,并检查它们的和是否为xsample会随机从数组中选择一个项目,这意味着您的代码的作用是“如果我的数组中有一对数字相加等于x,则有时返回true”。

我借用了您的方法名称.. 请不要介意.. :) - Arup Rakshit

0

只需遍历一次并使用目标数字查看是否匹配。比这里大多数答案快100倍

numbers = ( -10..10 ).to_a
numbers.unshift( numbers.first + -1 ) # if you do -20 or 20
numbers.push( numbers.last + 1 )
target    = 5
searched  = { }
matches   = { }
numbers.each do |number|
  if searched[ target - number + 1 ] == true
    matches[ "#{ number }_plus_#{ target - number }" ] = target
  end
  searched[ number + 1 ] = true
end
ap matches

0
def array_is_equal? (num_array, x) 
  equality = 0
  num_array.each do |a|
    equality += 1 if a == x
    return true if equality == 2
  end
  return false
end

在 Ruby 中,变量使用小写字母和下划线。这里的约定与其他一些语言不同。


我不确定这是否是原帖作者的意思 - 你计算的是有两个或更多元素等于 x,而原帖作者想要的是两个元素的 等于 x。顺便说一下,你编写的代码可以通过 num_array.count(x) > 1 实现。 - Uri Agassi

0

一行代码

x=[4,2,7,5]; x.each_with_index.any? {|y,i| x.each_with_index.any? {|z,j| unless i==j; z+y==11; end } }

作为一个函数

def pair_sum_match?(arr, x)
    arr.each_with_index.any? do |y,i|
        arr.each_with_index.any? do |z,j|
            unless i==j
                z+y==x
            end
        end
    end
end

更新:添加了each_with_index以避免在检查中包含自身。现在代码变得更长了 :-/


这也将为 [1,3,4] , 6 返回 true(它会将 3 与自身进行比较)。 - Uri Agassi
现在如果有相同的元素([1, 2, 3, 2]),你就会遇到问题了,而且 delete_if 会改变数组本身,因此你在进行操作时会破坏数组... - Uri Agassi
谢谢你指出这些问题,Uri。我希望我能用更少的代码来完成这个任务。 - 6ft Dan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接