我需要检查数组中任何2个元素的总和是否等于给定的数字。这就是我提出的,但它似乎没有进行比较
def sum_comparison(int_array, x)
n = int_array.length
(0..n).each do |i|
(1..n).each do |j|
if ((int_array[i].to_i + int_array[j].to_i) == x)
return true
else
return false
end
end
end
end
答案 0 :(得分:7)
你的解决方案似乎过于复杂,并且受到像C这样的低级过程语言的编程风格的强烈影响。一个明显的问题是你写的
n = int_array.length
(0..n).each do |i|
# use int_array[i].to_i inside the loop
end
现在在each
循环中,您将获得数字i = 0, 1, 2, ..., n
,例如int_array = [3,4,5]
获得i = 0, 1, 2, 3
。请注意,有四个元素,因为您从零开始计数(这被称为关闭一个错误)。这最终会导致n
的数组访问,这是一个超出数组末尾的访问。这将再次导致nil
返回,这可能是您使用to_i
将其转换回整数的原因,因为否则您将获得TypeError: nil can't be coerced into Fixnum
进行添加。您可能想要的只是:
int_array.each do |i|
# use i inside the loop
end
对于示例数组[3,4,5]
,这实际上会导致i = 3, 4, 5
。要以更Ruby方式获取数组的组合,您可以使用Array#combination
。同样,您可以使用Array#any?
检测是否有任何组合满足指定条件:
def sum_comparison(array, x)
array.combination(2).any? do |a, b|
a + b == x
end
end
答案 1 :(得分:5)
当你的函数比较第一个元素时,它会立即返回false。你需要在迭代时返回true,如果没有找到,则返回false,以避免这个问题:
def sum_comparison(int_array, x)
n = int_array.size
(0...n).each do |i|
(1...n).each do |j|
if (int_array[i].to_i + int_array[j].to_i) == x
return true
end
end
end
false
end
为简化此操作,您可以使用permutation
或combination
和any?
方法,如@ p11y所示。要获得已创建的元素,您可以使用find
or detect
。
def sum_comparison(a, x)
a.combination(2).any? { |i, j| i + j == x }
end
a.combination(2).detect { |i, j| i + j == x }
# sum_comparison([1,2,3, 4], 6) => [2, 4]
答案 2 :(得分:3)
使用枚举器:
#!/usr/bin/env ruby
def sum_comparison(int_array, x)
enum = int_array.to_enum
loop do
n = enum.next
enum.peek_values.each do |m|
return true if (n + m) == x
end
end
false
end
puts sum_comparison([1, 2, 3, 4], 5)
输出:
true
答案 3 :(得分:1)
<强>问题强>
您的方法相当于:
def sum_comparison(int_array, x)
return int_array[0].to_i + int_array[1].to_i == x
end
因此,
int_array = [1,2,4,16,32,7,5,7,8,22,28]
sum_comparison(int_array, 3) #=> true, just lucky!
sum_comparison(int_array, 6) #=> false, wrong!
<强>替代强>
这是一个相对有效的实施,当然比使用Enumerable#combination
更有效。
<强>代码强>
def sum_comparison(int_array, x)
sorted = int_array.sort
smallest = sorted.first
sorted_stub = sorted.take_while { |e| e+smallest <= x }
p "sorted_stub = #{sorted_stub}"
return false if sorted_stub.size < 2
loop do
return false if sorted_stub.size < 2
v = sorted_stub.shift
found = sorted_stub.find { |e| v+e >= x }
return true if found && v+found == x
end
false
end
<强>实施例强>
sum_comparison([7,16,4,12,-2,5,8], 3)
# "sorted_stub = [-2, 4, 5]"
#=> true
sum_comparison([7,16,4,12,-2,5,8], 7)
# "sorted_stub = [-2, 4, 5, 7, 8]"
#=> false
sum_comparison([7,16,4,22,18,12,2,41,5,8,17,31], 9)
# "sorted_stub = [2, 4, 5, 7]"
#=> true
备注强>
仅包含行p "sorted_stub = #{sorted_stub}"
以显示示例中的数组sorted_stub
。
对e+smallest > x
和f
,g
sorted
中g >= e
和f < g
的任何元素f+g >= e+smallest > x
sorted_stub.last
}。因此,sorted
是v
中需要考虑的最大值。
对于给定值found = sorted_stub.find { |e| v+e >= x }
,第e
行会在找到v+e = x
e
后立即停止搜索v+e >= x
{{1}}这样{{1}}。然后,下一行确定是否找到了匹配项。