代码之家  ›  专栏  ›  技术社区  ›  Dmitry Dmitriev

Ruby,无法解释的reduce行为

  •  0
  • Dmitry Dmitriev  · 技术社区  · 6 年前

    祝你好运。解决一种 '查找唯一值' 不同编程竞赛中的问题都使用此代码 arr.reduce(:^) :

    例如,这样的任务 您将得到一个奇数长度的整数数组,其中除一个数字外,所有整数都相同。查找此号码 通常通过以下方式解决: [8,8,8,5,8,8,8].reduce(:^) # 5

    我开始做实验,发现这个解决方案有一个差距,就是:

    p [8,2,2].reduce(:^) # 8
    p [8,2,2,2].reduce(:^) # 10 !!!!!!!!
    p [8,2,2,2,2].reduce(:^) # 8
    

    我发现在任何数组格式中 [x,y,y,y] 这个 x 找不到 reduce(:^) :

    p x = rand(1..100)
    p y = rand(1..100)
    p [x, y, y, y].reduce(:^) == x # FALSE (!)
    puts "But!"
    p [x, y, y ].reduce(:^) == x # true
    p [x, y, y, y, y ].reduce(:^) == x # true
    

    为什么会这样?(我的ruby是MRI 2.3.0)

    2 回复  |  直到 6 年前
        1
  •  2
  •   Aleksei Matiushkin    6 年前

    您将获得 奇数长度 整数数组。。。

    情况如何 [8, 2, 2, 2] 奇数长度?

    第三个 2 永远不会被XOR输出。人们可以一步一步地检查这一点:

    8 ^ 2
    #⇒ 10
    8 ^ 2 ^ 2
    #⇒ 8 # because 2 and 2 are XOR’ed out
    8 ^ 2 ^ 2 ^ 2
    #⇒ 10 # because it’s the same as 8 ^ 2
    

    此外:

    2 ^ 2 ^ 2
    #⇒ 2
    
        2
  •  1
  •   lacostenycoder    6 年前

    @mudasobwa的回答是正确的。但是,要了解更多信息,您可能需要了解:

    https://www.calleerlandsson.com/rubys-bitwise-operators/

    对于您的用例,您最好使用:

    [8,2,2,2].inject{|i,n| i > n ? i : n}
    

    让我们看看引擎盖下面发生了什么:

    def max_array_int(arr)
      arr.inject do |i,n|
        check = i > n ? i : n
        puts "evaluated #{i} > #{n}. result: #{check}"
        check
      end
    end
    
    max_array_int [10,3,15,7]