Arrays 如何返回数组中的第三大数

Arrays 如何返回数组中的第三大数,arrays,ruby,while-loop,Arrays,Ruby,While Loop,我回答编程问题的代码逻辑是: 查找输入数组中的最大数字 将该数字存储在新数组中 从输入数组中删除该数字 重复#的1-3,直到新数组中有三个元素 选择要返回的数组的最后一个元素 我的代码返回三个10,而不是数组中最大的三个元素10、8和4。我认为这可能是因为一旦完成了内部while循环,代码就无法返回到它了 我的测试代码是: puts(third_greatest([8, 1, 10, 4])).to_s 我的代码是: def third_greatest(nums) greatest_nu

我回答编程问题的代码逻辑是:

  • 查找输入数组中的最大数字
  • 将该数字存储在新数组中
  • 从输入数组中删除该数字
  • 重复#的1-3,直到新数组中有三个元素
  • 选择要返回的数组的最后一个元素
  • 我的代码返回三个10,而不是数组中最大的三个元素10、8和4。我认为这可能是因为一旦完成了内部while循环,代码就无法返回到它了

    我的测试代码是:

    puts(third_greatest([8, 1, 10, 4])).to_s
    
    我的代码是:

    def third_greatest(nums)
      greatest_number = nil
      three_greatest = []
    
      three_greatest_idx = 0
    
      while three_greatest_idx < 3
        number_idx = 0
    
        while number_idx < nums.length
          current_number = nums[number_idx]
    
          if greatest_number == nil
            greatest_number = current_number
          elsif greatest_number < current_number
            greatest_number = current_number
          end
    
          number_idx += 1
        end
    
        three_greatest.unshift(greatest_number)
        nums.delete(greatest_number)
        three_greatest_idx += 1
      end
    
      return three_greatest
    end
    
    def第三大(nums)
    最大值=零
    三个最大的=[]
    三个最大的idx=0
    而三个最大的idx<3
    数字_idx=0
    而数字_idx
    一旦你开始考虑用Ruby的方式来解决这样的问题,我的意思是更多地依靠一系列简单的操作来表达你的意图,这些操作通常是链接在一起的,那么解决方案就会变得更容易找到

    例如,要查找任意数组中的三个最高数字,显而易见的解决方案可能是:

    def three_greatest(list)
      list.sort.reverse.first(3)
    end
    
    这将对列表进行排序,默认情况下,列表从低到高,然后将其反转,使其从高到低。最后一个操作是复制前三个实体。这似乎很合理,因为它非常清楚地表达了您的意图,并且运行得非常好

    问题是,如果您更仔细地查看可枚举产品,则有一个更简单的解决方案,使用:

    这里要学习的经验是,可枚举库与机械师的工具箱不同,它有大量有用的工具。重要的是,至少花些时间通读其中的内容,这样你就不会浪费时间重新发明那些已经以优雅的形式存在的东西


    换句话说,在解决问题时,检查问题是否已经解决。在许多情况下,您会发现有一个工具可以完全满足您的需求。

    您忘记了取消设置
    最大值

      nums.delete(greatest_number)
      three_greatest_idx += 1
      greatest_number = nil # this line
    end
    

    显然,在Ruby中有一个非常简单的解决方案,但我想当然地认为您希望自己完成这项工作。

    对其进行排序,并对数组使用Ruby的负索引选项

    [8, 1, 10, 4].sort[-3]
    >> 4
    
    编辑:经过多次测试,如果在m个元素的数组中搜索第n个最大数时,n>m大小的1/20,则我确定上面显示的排序方法比下面的方法快。因为在您的示例中,我们在4个元素的数组中查找第三大数字,3比.2大得多,所以上面的答案比这个替代方法要有效得多:

    [8, 1, 10, 4].max(3)[-1]
    >> 4
    

    我假设这是一项不允许大量使用
    Enumerable
    模块的任务。还有更简单的方法。例如,您不需要维护另一个阵列:只需将最高的阵列从原始阵列中删除N次:

    def nth_greatest(nums, n)
      nums = nums.dup # prevent mutating the original array
      result = nil
      n.times do
        idx, max = -1, -Float::INFINITY
        nums.length.times do |i|
          idx, max = [i - 1, nums[i - 1]] if nums[i - 1] > max
        end
        result = nums.delete_at idx
      end
      result
    end
    
    nth_greatest [8, 1, 10, 4], 2
    #⇒ 8
    nth_greatest [8, 1, 10, 4], 3
    #⇒ 4
    

    为了帮助人们理解
    max
    sort
    和不使用内置方法之间的性能差异:

    require 'fruity'
    
    ary = (1..100).to_a.shuffle
    
    def use_max(a)
      a.max(3).last
    end
    
    def use_sort(a)
      a.sort[-3]
    end
    
    def nth_greatest(nums, n)
      nums = nums.dup # prevent mutating the original array
      result = nil
      n.times do
        idx, max = -1, -Float::INFINITY
        nums.length.times do |i|
          idx, max = [i - 1, nums[i - 1]] if nums[i - 1] > max
        end
        result = nums.delete_at idx
      end
      result
    end
    
    compare do
      sorted { use_sort(ary) }
      maxed  { use_max(ary) }
      nth_greatested { nth_greatest(ary, 3) }
    end
    
    # >> Running each test 512 times. Test will take about 1 second.
    # >> sorted is faster than maxed by 2x ± 0.1
    # >> maxed is faster than nth_greatested by 3x ± 0.1
    
    增加阵列的大小:

    ary = (1..1_000).to_a.shuffle
    
    ary = (1..100).to_a.shuffle
    
    # >>            user     system      total        real
    # >> sort   0.000000   0.000000   0.000000 (  0.000020)
    # >> max    0.000000   0.000000   0.000000 (  0.000013)
    # >>            user     system      total        real
    # >> sort   0.000000   0.000000   0.000000 (  0.000013)
    # >> max    0.000000   0.000000   0.000000 (  0.000011)
    # >>            user     system      total        real
    # >> sort   0.000000   0.000000   0.000000 (  0.000010)
    # >> max    0.000000   0.000000   0.000000 (  0.000010)
    # >>            user     system      total        real
    # >> sort   0.000000   0.000000   0.000000 (  0.000009)
    # >> max    0.000000   0.000000   0.000000 (  0.000010)
    # >>            user     system      total        real
    # >> sort   0.000000   0.000000   0.000000 (  0.000009)
    # >> max    0.000000   0.000000   0.000000 (  0.000010)
    # >>            user     system      total        real
    # >> sort   0.000000   0.000000   0.000000 (  0.000008)
    # >> max    0.000000   0.000000   0.000000 (  0.000010)
    # >>            user     system      total        real
    # >> sort   0.000000   0.000000   0.000000 (  0.000008)
    # >> max    0.000000   0.000000   0.000000 (  0.000010)
    # >>            user     system      total        real
    # >> sort   0.000000   0.000000   0.000000 (  0.000008)
    # >> max    0.000000   0.000000   0.000000 (  0.000013)
    # >>            user     system      total        real
    # >> sort   0.000000   0.000000   0.000000 (  0.000011)
    # >> max    0.000000   0.000000   0.000000 (  0.000010)
    # >>            user     system      total        real
    # >> sort   0.000000   0.000000   0.000000 (  0.000008)
    # >> max    0.000000   0.000000   0.000000 (  0.000010)
    
    结果:

    # >> Running each test 64 times. Test will take about 1 second.
    # >> maxed is faster than sorted by 80.0% ± 10.0%
    # >> sorted is faster than nth_greatested by 3x ± 0.1
    
    # >> Running each test 8 times. Test will take about 1 second.
    # >> maxed is faster than sorted by 3x ± 0.1
    # >> sorted is faster than nth_greatested by 2x ± 0.1
    
    并再次增大阵列大小:

    ary = (1..10_000).to_a.shuffle
    
    结果:

    # >> Running each test 64 times. Test will take about 1 second.
    # >> maxed is faster than sorted by 80.0% ± 10.0%
    # >> sorted is faster than nth_greatested by 3x ± 0.1
    
    # >> Running each test 8 times. Test will take about 1 second.
    # >> maxed is faster than sorted by 3x ± 0.1
    # >> sorted is faster than nth_greatested by 2x ± 0.1
    

    文档中没有提到max(3)是否返回一个反向排序的数组,即使它看起来像这样

    文档示例为:

    a.max(2) #=> ["horse", "dog"]
    
    这是下降的,但这不是一个好例子,因为使用数字更容易看到:

    ary.max(3) # => [100, 99, 98]
    

    以下是使用基准测试显示基线速度的一些结果:

    require 'benchmark'
    
    ary = (1..5).to_a.shuffle
    
    10.times do
      Benchmark.bm(4) do |b|
        b.report('sort') { ary.sort[-3] }
        b.report('max') { ary.max(3).last }
      end
    end
    
    # >>            user     system      total        real
    # >> sort   0.000000   0.000000   0.000000 (  0.000010)
    # >> max    0.000000   0.000000   0.000000 (  0.000006)
    # >>            user     system      total        real
    # >> sort   0.000000   0.000000   0.000000 (  0.000003)
    # >> max    0.000000   0.000000   0.000000 (  0.000004)
    # >>            user     system      total        real
    # >> sort   0.000000   0.000000   0.000000 (  0.000003)
    # >> max    0.000000   0.000000   0.000000 (  0.000004)
    # >>            user     system      total        real
    # >> sort   0.000000   0.000000   0.000000 (  0.000003)
    # >> max    0.000000   0.000000   0.000000 (  0.000003)
    # >>            user     system      total        real
    # >> sort   0.000000   0.000000   0.000000 (  0.000003)
    # >> max    0.000000   0.000000   0.000000 (  0.000004)
    # >>            user     system      total        real
    # >> sort   0.000000   0.000000   0.000000 (  0.000003)
    # >> max    0.000000   0.000000   0.000000 (  0.000004)
    # >>            user     system      total        real
    # >> sort   0.000000   0.000000   0.000000 (  0.000005)
    # >> max    0.000000   0.000000   0.000000 (  0.000005)
    # >>            user     system      total        real
    # >> sort   0.000000   0.000000   0.000000 (  0.000003)
    # >> max    0.000000   0.000000   0.000000 (  0.000004)
    # >>            user     system      total        real
    # >> sort   0.000000   0.000000   0.000000 (  0.000003)
    # >> max    0.000000   0.000000   0.000000 (  0.000003)
    # >>            user     system      total        real
    # >> sort   0.000000   0.000000   0.000000 (  0.000003)
    # >> max    0.000000   0.000000   0.000000 (  0.000003)
    
    以及增加阵列的大小:

    ary = (1..1_000).to_a.shuffle
    
    ary = (1..100).to_a.shuffle
    
    # >>            user     system      total        real
    # >> sort   0.000000   0.000000   0.000000 (  0.000020)
    # >> max    0.000000   0.000000   0.000000 (  0.000013)
    # >>            user     system      total        real
    # >> sort   0.000000   0.000000   0.000000 (  0.000013)
    # >> max    0.000000   0.000000   0.000000 (  0.000011)
    # >>            user     system      total        real
    # >> sort   0.000000   0.000000   0.000000 (  0.000010)
    # >> max    0.000000   0.000000   0.000000 (  0.000010)
    # >>            user     system      total        real
    # >> sort   0.000000   0.000000   0.000000 (  0.000009)
    # >> max    0.000000   0.000000   0.000000 (  0.000010)
    # >>            user     system      total        real
    # >> sort   0.000000   0.000000   0.000000 (  0.000009)
    # >> max    0.000000   0.000000   0.000000 (  0.000010)
    # >>            user     system      total        real
    # >> sort   0.000000   0.000000   0.000000 (  0.000008)
    # >> max    0.000000   0.000000   0.000000 (  0.000010)
    # >>            user     system      total        real
    # >> sort   0.000000   0.000000   0.000000 (  0.000008)
    # >> max    0.000000   0.000000   0.000000 (  0.000010)
    # >>            user     system      total        real
    # >> sort   0.000000   0.000000   0.000000 (  0.000008)
    # >> max    0.000000   0.000000   0.000000 (  0.000013)
    # >>            user     system      total        real
    # >> sort   0.000000   0.000000   0.000000 (  0.000011)
    # >> max    0.000000   0.000000   0.000000 (  0.000010)
    # >>            user     system      total        real
    # >> sort   0.000000   0.000000   0.000000 (  0.000008)
    # >> max    0.000000   0.000000   0.000000 (  0.000010)
    
    以及:


    你是如何处理重复的?这个问题实际上是重复的。很好。我从未注意到max的可选参数。非常合理的建议,谢谢。我一定会在解决下一个问题时检查。我正在审查问题的程序给了我一组受限的Ruby信息,因为他们声称这是我完成编码挑战所需要知道的全部。但是你是对的,我不应该限制自己,开始更多地探索Ruby的世界。再次感谢你!顺便说一句,你需要
    list.max(3).last
    来回答这个问题。^这个。这是一篇很棒的帖子,请给出答案。@Eric,可选参数是在Ruby v2.2中添加的
    min
    min\u by
    max\u by
    也得到了它。哈哈,是的,我确实想自己做这件事,因为(正如你所说)我对Ruby还不熟悉。非常感谢你,你太棒了!它是有效的,但是仅仅为了找到3个元素而对整个数组进行排序是有点过分了。当然,对于3元素数组,很难编写一个低效的排序算法。不过,您的排序应用于N个元素。请参见@theTinMan答案。对于5个元素数组,
    sort
    max
    的执行速度几乎不需要使用基准测试和最快的反弹,因此使用其中一个并不重要。在500个元素时
    max
    的速度几乎不快,但它是一致的。如果有什么不同的话,我会追求红宝石金色徽章。我一点也不在乎评论。我确实认为StackOverflow是一个学习的好地方,我个人非常喜欢得到建设性的批评。当有人告诉我我写的东西不是最好的时,我不会把它当作个人的事情。我试着理解为什么,下次再做得更好。我不是有意冒犯你的。我的评论只是告诉你,有100个元素(这似乎是合理的),没有必要对97个最小的元素进行排序。真的没有必要侮辱任何人。对所有解决方案进行基准测试会很有趣。我想知道什么是单程单程