Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
检查数组中的2个数字在Ruby中是否和为0_Ruby_Arrays - Fatal编程技术网

检查数组中的2个数字在Ruby中是否和为0

检查数组中的2个数字在Ruby中是否和为0,ruby,arrays,Ruby,Arrays,我已经研究这个问题几个小时了,我不明白为什么我不能让它正常运行。这种方法的最终目的是让数组中的两个数字相加等于零。这是我的密码: def two_sums(nums) i = 0 j = -1 while i < nums.count num_1 = nums[i] while j < nums.count num_2 = nums[j] if num_1 + num_2 == 0

我已经研究这个问题几个小时了,我不明白为什么我不能让它正常运行。这种方法的最终目的是让数组中的两个数字相加等于零。这是我的密码:

def two_sums(nums)
    i = 0
    j = -1
    while i < nums.count
        num_1 = nums[i]
        while j < nums.count
        num_2 = nums[j]
            if num_1 + num_2 == 0
                return "There are 2 numbers that sum to zero & they are #{num_1} and #{num_2}."
            else
                return "Nothing adds to zero."
            end             
        end
    i += 1
    j -= 1
    end
end
我遇到的问题是,除非数组中的第一个和最后一个数字是同一个数字的正数和负数,否则它将始终返回false


例如,如果我有一个数组是[1,4,6,-1,10],它应该返回true。我确信我的2 while语句是造成这一问题的原因,但我想不出解决的办法。如果有人能给我指出正确的方向,那会很有帮助。

好吧,鉴于它被标记为ruby,下面是我能想到的解决这个问题的最简单的ruby方法:

def two_sums(arr)
  numbers = arr.combination(2).select { |a| a.reduce(:+) == 0 }.flatten

  if numbers.empty?
    "Nothing adds to zero."
  else
    "There are 2 numbers that sum to zero & they are #{numbers.first} and #{numbers.last}."
  end
end

您可以找到相加为0的第一对,如下所示:

nums.combination(2).find { |x, y| x + y == 0 }
#=> returns the first matching pair or nil
def two_sums(nums)
  pair = nums.combination(2).find { |x, y| x + y == 0 }
  if pair
    "There are 2 numbers that sum to zero & they are #{pair.first} and #{pair.last}."
  else
    "Nothing adds to zero."
  end
end    
或者,如果要选择相加为0的所有对:

nums.combination(2).select { |x, y| x + y == 0 }
#=> returns all matching pairs or an empty array
因此,您可以实现如下方法:

nums.combination(2).find { |x, y| x + y == 0 }
#=> returns the first matching pair or nil
def two_sums(nums)
  pair = nums.combination(2).find { |x, y| x + y == 0 }
  if pair
    "There are 2 numbers that sum to zero & they are #{pair.first} and #{pair.last}."
  else
    "Nothing adds to zero."
  end
end    
或者,如果要查找所有对:

def two_sums(nums)
  pairs = nums.combination(2).select { |x, y| x + y == 0 }
  if pairs.empty?
    "Nothing adds to zero."
  else
    "The following pairs sum to zero: #{pairs}..."
  end
end    

我认为最简单的方法是:

nums.combination(2).any? { |x,y| (x+y).zero? }

这里有一种适合大型阵列的方法。上面的方法通过两个数字的每一个可能的组合,对于小的情况来说都是非常好的,但是对于包含大量元素的数组来说,速度会非常慢,内存会非常紧张

def two_sums nums
  h = Hash.new
  nums.each do |n|
    return true if h[-n]
    h[n] = true
  end
  false
end
还有一种方法:

代码

例子

这种方法比较快。让我们尝试使用200000个元素的数组,每个元素都是-500000到500000之间的随机数

require 'time'

t = Time.now
arr = Array.new(200_000) { rand(1_000_001) - 500_000 }
arr.size #=> 200000

sum_to_zero(arr).size #=> 16439
Time.now - t
  #=> 0.23 (seconds) 

sum_to_zero(arr).first(6)
  #=> [[-98747, 98747],
  #    [157848, -157848],
  #    [-459650, 459650],
  #    [176655, 176655, -176655],
  #    [282101, -282101],
  #    [100886, 100886, -100886]]
如果要将总和为零的非负值和负值分组:

sum_to_zero(arr).map { |a| a.partition { |e| e >= 0 } }.first(6)
  #=> [[[98747], [-98747]],
  #    [[157848], [-157848]],
  #    [[459650], [-459650]],
  #    [[176655, 176655], [-176655]],
  #    [[282101], [-282101]],
  #    [[100886, 100886], [-100886]]]
如果每个组只需要一个非负值的值,请说:

sum_to_zero(arr).map { |a| a.first.abs }.first(6)
  #=> [98747, 157848, 459650, 176655, 282101, 100886]

哇,我还是Ruby的新手,所以我能识别90%的代码。还没有达到。减少或。组合。谢谢你的帮助wicz!:因为您知道a是一个两元素数组,所以使用a.reduce:+计算x+y是一种非常复杂的方法。只需选择{| x,y | x+y==0}对于小的情况,这是很好的。但是由于这些方法都在^2上,如果你有大的案例,你会想要一个Onlogn或On方法,你绝对是对的@JKillian。首先对数组进行排序,并让数组两端的指针查找匹配对,这样会更有效。但在我看来,这个问题是关于使代码工作和可读性,而不是关于改进运行时。同意,您的答案适用于大多数情况。为了好玩和提高理论效率,我发布了一个使用哈希的答案。我觉得这段代码非常难看!有没有办法让它看起来更漂亮,但功能却保持不变?非常好!我修改它以返回满足求和为零要求的所有n>=0,并对我在回答中给出的200000个元素的随机数组运行它。它是闪电般的快!代码如下:h={};nums.each|u with|u object[]{n,a | h[n]=true;a[361248,209826,277499,32486156859,112086]。使其需要'set';nums.each|u with|objectSet.new{n,s|h[n]=true;s整洁的方法,我认为这也应该是线性时间,因为group_by应该是线性的,而.uniq应该只需要遍历每个值一次,所以也应该是线性时间。就像一个小小的吹毛求疵一样,我相信a.size>1条件在主方法中是多余的definition@JKillan,我们必须确保uded,包含零的数组的大小必须至少为2。但是,我所做的可以改进,我已经做了修复。谢谢您的提醒。
array.combination(2).select{|x|x[0] + x[1] == 0}