我怎样才能改进这种超级简单的排序方法? - 开始Ruby

时间:2017-01-13 02:57:25

标签: ruby

我从Chris Pine学习Ruby"学习编程"本书和我被要求编写一种方法,用循环或递归按字母顺序对一组给定的单词进行排序。我首先尝试循环。

def sort words
    i = 0
    checked = 0
    while true
        if (i+1 < words.length)
            if (words[i]>words[i+1])
                temp = words[i] 
                words[i] = words[i+1]
                words[i+1] = temp
            else
                checked+=1
            end 
            i+=1
        elsif (checked == words.length-1)
            break
        else
            i =0
            checked =0
        end
    end
    return words
end

代码有效,但我想知道是否有任何经验丰富的红宝石可以提供一些如何使其更有效的输入。

谢谢!

2 个答案:

答案 0 :(得分:4)

当您开始理解优化时,首先要了解的是,最明显的修复通常效率最低。例如,您可以花费大量时间来调整其中一些比较,或者转换为稍微不同的方式来评估相同的事情并获得5-10%的性能提升。

您还可以使用完全不同的算法,并获得5x-10x的增加。冒泡排序,这就是你所拥有的,几乎是有史以来表现最差的排序算法。这是一种你应该学习的技巧,只要理解它很糟糕,你就应该立即转向其他方法,比如Quicksort,如果你系统地解决问题,那就不是那么难以实现的。< / p>

换句话说,在你开始调整一些小事情之前,先退后一步,问问自己&#34;我是否正确地解决了这个问题?&#34;遇到性能问题时,请始终考虑其他角度。

话虽如此,这里是如何使你的代码更像Ruby:

def sort(words)
  # Make a copy so the original isn't mangled
  words = words.dup

  # Iterate over ranges:
  #   (n..m) goes from N to M inclusive
  #   (n...m) goes from N up to but not including M
  (0...words.length-1).each do |i|
    (0...words.length-1-i).each do |j|
      # Examine the pair of words at this offset using an array slice
      a, b = words[j, 2]

      # If A is ahead of B then...
      if (a > b)
        # ...swap these elements.
        words[j, 2] = [ b, a ]
      end
    end
  end

  words
end

# Quick test function that uses randomized data
p sort(%w[ a c d f b e ].shuffle)

作为开发人员,您应该始终尝试以某种方式衡量您的进度。像Rubocop这样的工具将有助于识别低效的编码实践。测试驱动的开发有助于在编程早期识别缺陷并确保更改不会导致回归。基准测试工具可帮助您更好地理解代码的性能。

例如:

require 'benchmark'

CHARS = ('a'..'z').to_a

def random_data
  Array.new(1000) { CHARS.sample }
end

count = 100

Benchmark.bm do |bm|
  bm.report('my sort:') do
    count.times do
      sort(random_data)
    end
  end

  bm.report('built-in sort:') do
    count.times do
      random_data.sort
    end
  end
end

#                     user     system      total        real
# my sort:       19.220000   0.060000  19.280000 ( 19.358073)
# built-in sort:  0.030000   0.000000   0.030000 (  0.025662)

因此该算法比内置方法慢642倍。我相信你可以通过更好的算法更接近。

答案 1 :(得分:0)

首先,你不必重新发明轮子。我的意思是,看看这个例子:

> ['a', 'abc', 'bac', 'cad'].sort
# => ["a", "abc", "bac", "cad"]

Ruby拥有大量庞大的库。 Ruby非常有效地支持常见的东西。您必须有足够的知识才能有效地使用语言功能。

我建议您浏览Ruby核心库并学习如何结合使用这些功能来实现特殊功能。

试试这个Ruby Koans http://rubykoans.com/

RubyKoans是实现掌握Ruby语言最有效的方法。

  

以下是此网站https://www.sitepoint.com/sorting-algorithms-ruby/

中按类型排序算法示例的列表      

您必须根据问题域和用例的大小明智地选择算法。