数组中对象的Ruby和等于零

数组中对象的Ruby和等于零,ruby,arrays,Ruby,Arrays,编写一个方法,查找一个数字数组是否有一个和为零的对。注意零的情况;数组中需要有两个零才能形成一个和为零的对 下面是我写的代码,但我知道它是错误的。我知道在某个时刻它会添加自身,所以如果数组中只有一个0,那么它仍然会返回true。我是编程和Ruby新手,所以任何建议都将非常感谢 谢谢 def has_zero?(array) left, right = [-1,1] lefter=[] righter=[] righter=a

编写一个方法,查找一个数字数组是否有一个和为零的对。注意零的情况;数组中需要有两个零才能形成一个和为零的对

下面是我写的代码,但我知道它是错误的。我知道在某个时刻它会添加自身,所以如果数组中只有一个0,那么它仍然会返回true。我是编程和Ruby新手,所以任何建议都将非常感谢

谢谢

    def has_zero?(array)
        left, right = [-1,1]
        lefter=[]
        righter=[]
        righter=array.each {|x| x+= array[right]}
        lefter=array.each {|x| x+= array[left]}
        if lefter.include?(0) || righter.include?(0)
            return true
        else return false
        end
        left,right = [left-1,right+1]
    end

Ruby有一些内置的方法,使这变得非常简单:

def has_zero_sum_pair?(a)
  a.permutation(2).any?{|pair| pair.inject(:+) == 0}
end
a.permutation(2)
为您提供
a
中的每一对<代码>任何?如果块曾经返回
true
,则返回
true
<代码>注入(:+)是获取数组和的简单方法

has_zero_sum_pair?([1, 2, 3])
# => false 
has_zero_sum_pair?([1, 2, 3, -2])
# => true 
has_zero_sum_pair?([1, 2, 3, 0])
# => false 
has_zero_sum_pair?([0, 1, 2, 3, 0])
# => true
更新:如果我不知道并且必须以我想到的第一种方式完成这项工作,或者如果我关心性能,我可能会这样做:

def has_zero_sum_pair2?(a)
  (0..a.length-2).each do |i|
    (i+1..a.length-1).each do |j|
      return true if a[i] + a[j] == 0
    end
  end
  false
end
我发现这更难看,更容易出错,而且写起来也花了更长的时间。但小型阵列的速度大约是小型阵列的四倍,大型阵列的速度大约是大型阵列的十倍。在编程中,通常使用一种简单的方法,这种方法在大多数情况下都能很好地工作,但在性能上并不理想。有时,通过选择更好的算法或数据结构,可以在不牺牲清晰度的情况下获得更好的性能。通常必须进行权衡


更新2:如果我真的关心性能,我会使用@FMc的技术。这是使用更好的数据结构和算法获得巨大性能提升的一个很好的例子。

Ruby有一些内置的方法使这变得非常简单:

def has_zero_sum_pair?(a)
  a.permutation(2).any?{|pair| pair.inject(:+) == 0}
end
a.permutation(2)
为您提供
a
中的每一对<代码>任何?如果块曾经返回
true
,则返回
true
<代码>注入(:+)是获取数组和的简单方法

has_zero_sum_pair?([1, 2, 3])
# => false 
has_zero_sum_pair?([1, 2, 3, -2])
# => true 
has_zero_sum_pair?([1, 2, 3, 0])
# => false 
has_zero_sum_pair?([0, 1, 2, 3, 0])
# => true
更新:如果我不知道并且必须以我想到的第一种方式完成这项工作,或者如果我关心性能,我可能会这样做:

def has_zero_sum_pair2?(a)
  (0..a.length-2).each do |i|
    (i+1..a.length-1).each do |j|
      return true if a[i] + a[j] == 0
    end
  end
  false
end
我发现这更难看,更容易出错,而且写起来也花了更长的时间。但小型阵列的速度大约是小型阵列的四倍,大型阵列的速度大约是大型阵列的十倍。在编程中,通常使用一种简单的方法,这种方法在大多数情况下都能很好地工作,但在性能上并不理想。有时,通过选择更好的算法或数据结构,可以在不牺牲清晰度的情况下获得更好的性能。通常必须进行权衡


更新2:如果我真的关心性能,我会使用@FMc的技术。这是使用更好的数据结构和算法获得巨大性能提升的一个很好的例子。

除了零之外,这是有效的

[1, 2, 3, -2]
.uniq.group_by(&:abs).any?{|_, tuple| tuple.length == 2}
# => true

除了零之外,这是有效的

[1, 2, 3, -2]
.uniq.group_by(&:abs).any?{|_, tuple| tuple.length == 2}
# => true

这个问题需要一个
散列

vals = [0, 4, 3, 0, -3, 2, -2, 1, 3, -4, -4]

# Our hash:
# groups[X] = Array of vals equal to X
groups = vals.group_by { |v| v }

# Just check whether the hash contains a pair
# of keys X and -X, or whether the original array
# had more than one zero in it.
p groups.any? { |k, vs| k == 0 ? vs.size > 1 : groups.has_key?(-k) }
您可以通过稍微更改测试来概括任何
目标
总和:

k == target / 2 ? vs.size > 1 : groups.has_key?(target - k)

这个问题需要一个
散列

vals = [0, 4, 3, 0, -3, 2, -2, 1, 3, -4, -4]

# Our hash:
# groups[X] = Array of vals equal to X
groups = vals.group_by { |v| v }

# Just check whether the hash contains a pair
# of keys X and -X, or whether the original array
# had more than one zero in it.
p groups.any? { |k, vs| k == 0 ? vs.size > 1 : groups.has_key?(-k) }
您可以通过稍微更改测试来概括任何
目标
总和:

k == target / 2 ? vs.size > 1 : groups.has_key?(target - k)
检查是否有任何项目的负数在数组中更靠右。(rindex查找数组中最后一次出现的索引。)


检查是否有任何项目的负数在数组中更靠右。(rindex找到数组中最后一次出现的索引。)

我建议将不使用
inject
的版本与使用它的版本一起显示,以使初学者更清楚地了解它在做什么:)作为警告:
排列
在数组变大时会变得非常慢。是的,还有更多的“初学者”吗不使用“排列”的方法?我上周刚开始学习编程,我甚至不知道注入方法。thanks@user2391263要做到这一点,还有更难的方法。作为一个初学者,如果有的话,依靠内置的方法更有意义。参考文档并了解Ruby为您提供的内容是可以的,也是值得鼓励的。谢谢,但是“参考文档”是什么意思?最好的方法是什么?抱歉,我是一个完全的编程初学者。我建议在使用它的版本旁边显示不带
inject
的版本,以便让初学者更清楚它在做什么:)作为警告:
permutation
在数组变大时会变得非常慢。是的,有没有更“初学者”的方法不用“permutation”来做这件事? 我上周刚开始学习编程,我甚至不知道注入方法。thanks@user2391263要做到这一点,还有更难的方法。作为一个初学者,如果有的话,依靠内置的方法更有意义。参考文档并了解Ruby为您提供的内容是可以的,也是值得鼓励的。谢谢,但是“参考文档”是什么意思?最好的方法是什么?很抱歉,我是一个完全的编程初学者。您的示例输入数据丢失。展示这一点,以及你所说的“有一对”是什么意思。有两个数字或两个连续的数字吗?不知道为什么这个问题以“太本地化”结尾。这是二和问题,是以下情况的一种变体:。缺少示例输入数据。展示这一点,以及你所说的“有一对”是什么意思。有两个数字或两个连续的数字吗?不知道为什么这个问题以“太本地化”结尾。这是二和问题,这是一个变体:。这很聪明,而且非常、非常快。顺便说一句:你的
groupby
在stdlib中尖叫着要一个标识函数。我的工具带中通常有一个:
ID=->x{x}
。然后,您的
groupby
变成
vals.groupby(&ID)
。如果你习惯了,比如说Haskell,在
前奏曲
中有一个
id
,这会更容易阅读。@JörgWMittag是的,我也这么想!我想我肯定忽略了什么。你发现了:。这很聪明,而且非常、非常快。顺便说一句:你的
groupby
在stdlib中尖叫着要一个身份函数。我爱我们