你有一个阵列。如果数组中任何两个数字加零,则返回true
。只要有一对加零,返回true
并不重要。如果存在零,则只有多个时才能返回true
。
我写了两个函数,一个用于检查每个函数,最后一个用于组合两者,如果不满足则返回false
。
def checkZero(array)
zerocount = 0
for j in 0..array.count
if array[j] == 0
zerocount += 1
end
end
if zerocount > 1 #this part seems to not be working, not sure why
return true
else
return false
end
end
def checkNegative(array)
for j in 0..array.count
neg = -array[j] #set a negative value of the current value
if array.include?(neg) #check to see whether the negative exists in the array
return true
else
return false
end
end
end
def checkArray(array)
if checkZero(array) == true or checkNegative(array) == true
return true
else
return false
end
end
然后运行类似
的内容array = [1,2,3,4,0,1,-1]
checkArray(array)
到目前为止,Ruby还没有回复任何东西。我只是得到一个空白。我有一种感觉return
是对的。
答案 0 :(得分:2)
问题可能是您没有输出结果。
array = [1,2,3,4,0,1,-1]
puts checkArray(array)
如果性能(O( n ^ 2))不是一个很大的问题,checkArray
方法可以写成如下所示:
def check_array(array)
array.combination(2).any?{|p| p.reduce(:+) == 0}
end
效率更高(O( n log n ))解决方案是:
def check_array(array)
array.sort! # `array = array.sort` if you need the original array unchanged
i, j = 0, array.size - 1
while i < j
sum = array[i] + array[j]
if sum > 0
j -= 1
elsif sum < 0
i += 1
else
return true
end
end
return false
end
答案 1 :(得分:2)
这里有一些相对有效的方法来检查两个值是否总和为零:
解决方案#1
def checkit(a)
return true if a.count(&:zero?) > 1
b = a.uniq.map(&:abs)
b.uniq.size < b.size
end
解决方案#2
def checkit(a)
return true if a.sort_by(&:abs).each_cons(2).find { |x,y| x == -y }
false
end
解决方案#3
def checkit(a)
return true if a.count(&:zero?) > 1
pos, non_pos = a.group_by { |n| n > 0 }.values
(pos & non_pos.map { |n| -n }).any?
end
解决方案#4
require 'set'
def checkit(a)
a.each_with_object(Set.new) do |n,s|
return true if s.include?(-n)
s << n
end
false
end
<强>实施例强>
checkit([1, 3, 4, 2, 2,-3,-5,-7, 0, 0]) #=> true
checkit([1, 3, 4, 2, 2,-3,-5,-7, 0]) #=> true
checkit([1, 3, 4, 2,-3, 2,-3,-5,-7, 0]) #=> true
checkit([1, 3, 4, 2, 2,-5,-7, 0]) #=> false
<强>说明强>
以下全部引用数组:
a = [1,3,4,2,2,-3,-5,-7,0]
<强>#1 强>
Zeroes存在一些问题,所以让我们首先看看是否有多个问题,在这种情况下我们已经完成了。由于a.count(&:zero?) #=> 1
,a.count(&:zero?) > 1 #=> false
,所以
return true if a.count(&:zero?) > 1
不会让我们回来。接下来,我们删除所有重复项:
a.uniq #=> [1, 3, 4, 2, -3, -5, -7, 0]
然后将所有数字转换为其绝对值:
b = a.uniq,map(&:abs) #=> [1, 3, 4, 2, 3, 5, 7, 0]
最后看看c
是否包含任何重复项,这意味着原始数组包含至少两个符号相反的非零数字:
c.uniq.size < c.size #=> true
<强>#2 强>
b = a.sort_by(&:abs)
#=> [0, 1, 2, 2, 3, -3, 4, -5, -7]
c = b.each_cons(2)
#=> #<Enumerator: [0, 1, 2, 2, 3, -3, 4, -5, -7]:each_cons(2)>
要查看枚举器的内容:
c.to_a
#=> [[0, 1], [1, 2], [2, 2], [2, 3], [3, -3], [-3, 4], [4, -5], [-5, -7]]
c.find { |x,y| x == -y }
#=> [3, -3]
返回如此真实。
<强>#3 强>
return true if a.count(&:zero?) > 1
#=> return true if 1 > 1
h = a.group_by { |n| n > 0 }
#=> {true=>[1, 3, 4, 2, 2], false=>[-3, -5, -7, 0]}
b = h.values
#=> [[1, 3, 4, 2, 2], [-3, -5, -7, 0]]
pos, non_pos = b
pos
#=> [1, 3, 4, 2, 2]
non_pos
#=> [-3, -5, -7, 0]
c = non_pos.map { |n| -n }
#=> [3, 5, 7, 0]
d = pos & c
#=> [3]
d.any?
#=> true
<强>#4 强>
require 'set'
enum = a.each_with_object(Set.new)
#=> #<Enumerator: [1, 3, 4, 2, 2, -3, -5, -7, 0]:each_with_object(#<Set: {}>)>
enum.to_a
#=> [[1, #<Set: {}>],
# [3, #<Set: {}>],
# ...
# [0, #<Set: {}>]]
将值传递到块中,分配给块变量并执行块,如下所示:
n, s = enum.next
#=> [1, #<Set: {}>]
s.include?(-n)
#=> #<Set: {}>.include?(-1)
#=> false
s << n
#=> #<Set: {1}>
n, s = enum.next
#=> [3, #<Set: {1}>]
s.include?(-3)
#=> false
s << n
#=> #<Set: {1, 3}>
...
n, s = enum.next
#=> [2, #<Set: {1, 3, 4, 2}>]
s.include?(-n)
#=> false
s << n
#=> #<Set: {1, 3, 4, 2}> # no change
n, s = enum.next
#=> [-3, #<Set: {1, 3, 4, 2}>]
s.include?(-n)
#=> true
导致true
返回。
答案 2 :(得分:1)
我无法重现您的代码的任何问题,但您可以使用combination
非常简洁地表达解决方案以获取所有可能的对,然后将每对与reduce
求和,最后检查是否有是zero?
:
[1,2,3,4,0,1,-1].combination(2).map { |pair| pair.reduce(:+) }.any?(&:zero?)
答案 3 :(得分:1)
这有点code review。让我们从第一种方法开始:
def checkZero(array)
Ruby命名约定是snake_case而不是camelCase。这应该是def check_zero(array)
现在循环:
zerocount = 0
for j in 0..array.count
if array[j] == 0
zerocount += 1
end
end
正如@AndrewMarshall所说,for
不是惯用的。 each
更可取。但是,在ruby中,在Array
和Enumerable
(包含在Array
中)中可用的所有方法几乎不需要在循环之前初始化变量。我强烈建议将这些方法提交到内存中。以上可以写
array.any? {|number| number.zero?}
或等效
array.any?(&:zero?)
现在,这部分:
if zerocount > 1 #this part seems to not be working, not sure why
return true
else
return false
end
end
每当你有模式
if (expr that returns true or false)
return true
else
return false
end
它可以简化为return (expr that returns true or false)
。如果它是方法的最后一个语句,你甚至可以省略return
。
全部放在一起:
def check_zero(array)
array.any?(&:zero?)
end
def check_zero_sum(array)
array.combination(2).any?{|a,b| a + b == 0}
end
def check_array(array)
check_zero(array) || check_zero_sum(array)
end
(注意我借用了Andrew check_zero_sum
的AndrewMarshall代码,我觉得这很容易理解,但@ CarySwoveland的回答会更快)
修改强>
我错过了check_zero
甚至不需要的事实,因为你至少需要一对,在这种情况下check_zero_sum
就是你所需要的。
def check_array(array)
array.combination(2).any?{|a,b| a + b == 0}
end