【问题标题】:Check for consecutive numbers检查连续的数字
【发布时间】:2016-01-03 14:22:21
【问题描述】:

我有一个整数数组m。我正在寻找一种方法来检查m 的元素是否连续。有没有办法测试连续数字?

我想出了这段代码,打算在数组长度为四时工作:

m.count == 4 && (m.max-m.min) == 3

对于[1,1,1,4][0,0,0,3] 错误地返回true

【问题讨论】:

  • 你想让[4,6,5,7]通过吗?
  • 最简单的?:m.count==4 && (m.size-1).times.all? { |i| m[i+1] == m[i] + 1 }.
  • @illusionist,有关连续整数的定义,请参阅this Wiki。所以[4,6,5,7] 应该返回false
  • [4, 3, 2, 1] 是连续的。您是否希望它仅在系列增加时通过?
  • @sawa,我提供的 Wiki 链接虽然不是权威的,但将连续整数序列定义为仅递增。

标签: arrays ruby integer conditional-statements


【解决方案1】:

Enumerable 有一个非常方便的方法,称为 each_cons,其工作原理如下:

[1,2,3,4].each_cons(2).to_a # => [ [1, 2], [2, 3], [3, 4] ]

也就是说,它产生每个连续的 n 个元素集。在我们的例子中,n 是 2。

当然,顾名思义,它返回一个 Enumerator,因此我们可以将它与其他 Enumerable 方法链接起来,例如 all?

def four_consecutive?(arr)
  return false unless arr.size == 4
  arr.each_cons(2).all? {|a, b| b == a + 1 }
end

four_consecutive?([2,3,4,5])   # => true
four_consecutive?([2,2,2,5])   # => false
four_consecutive?([1,2,3,4,5]) # => false

这种方法比其他方法有一个优势,因为all? 会在块返回 false 时立即短路,它只会测试数字,直到找到不满足条件的对 (b == a + 1)。当然,只有四个元素,这并没有真正的区别——除非你在性能很重要的情况下调用这个方法数千次。

【讨论】:

    【解决方案2】:

    你可以试试这个:

    a == (a.min..a.max).to_a && a.count == 4
    

    这仅在数组按升序排列时有效。 [3, 4, 5, 6] 会通过,但 [4, 3, 5, 6] 不会。

    【讨论】:

    • 我认为这不会通过` [4, 3, 5, 6] `
    • @illusionist,它应该返回 false。然而,有一个问题,因为a = [1,2,3] 返回true,即使a 不包含4 元素。
    • @CarySwoveland 编辑以考虑 a.count
    【解决方案3】:

    答案基于Sum of consecutive integers的数学问题

    Sum = n∗(n+1)/2
    

    代码:

    def check_sum_match?(arr)
      m = arr.min - 1
      n = arr.max
      sum1 = arr.inject{|sum, x| sum = sum + x}
      sum2 = (n*(n+1) - m*(m+1))/2
      sum1 == sum2
    end
    
    arr = [5,6,7,8]
    if arr.count == 4 && check_sum_match?(arr)
      puts 'Yes condition matches'
    else
      puts 'Invalid Array'
    end
    # valid arrays are
    # [4,6,5,7], [4,5,6,7], etc
    

    暂定说明:

    【讨论】:

    • 哇!印象深刻。为了理解它,我不得不写下一些数字,但绝对有效。你认为有另一种方法可以做到这一点而不变成方法吗?
    • 如你所说,[4,6,5,7] 返回true,但它应该是false,因为元素是不连续的。此外,[3,4,5] 会返回 true,即使它不包含 4 元素。
    • @CarySwoveland 我认为数组不需要排序。我也错过了。
    • 到目前为止有 6 个赞,其中大多数是在答案被证明不正确之后出现的!天啊!我很少投反对票,但我会破例,因为让一个不正确的答案站在那里是带着欲望、贪婪和骄傲的。
    【解决方案4】:

    如果a 是数组,n 是所需大小:

    def size_and_consecutive?(a, n)
      a == (a.first..(a.first+n-1)).to_a
    end
    
    size_and_consecutive? [3,4,5,6], 4
      #=> true
    size_and_consecutive? [4,3,5,6], 4
      #=> false
    size_and_consecutive? [3,4,5], 4
      #=> false
    

    【讨论】:

      【解决方案5】:

      我能想出的一个紧凑的解决方案如下:

      def consec(arr)
        is_of_proper_length = (arr.size == 4)
        if(is_of_proper_length)
          are_consec = true
          arr.each_cons(2) {|x,y| are_consec = false unless ((y - x) == 1)}
        end
        is_of_proper_length && are_consec
      end
      

      输出:

      consec([1,2,3,4])
       => true 
      2.2.0 :051 > consec([0,0,0,0])
       => false 
      2.2.0 :052 > consec([4,6,5,7])
       => true 
      2.2.0 :053 > consec([4,5,6,7])
       => true 
      2.2.0 :054 > consec([5,6,7,8])
       => true 
      2.2.0 :055 > consec([2,2,2,5])
       => false 
      2.2.0 :056 > consec([2,3,4,5])
       => true 
      2.2.0 :057 > consec([1,2,3,4,5])
       => false
      

      【讨论】:

      • [4,6,5,7]的元素不连续,所以应该返回false
      • 得到sorted_arr.last不需要排序,arr.max就足够了
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-01-16
      • 1970-01-01
      • 2022-11-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多