Reverse a string in Ruby

前端 未结 22 1044
广开言路
广开言路 2020-12-05 06:36

How do you reverse a string in Ruby? I know about string#reverse. I\'m interested in understanding how to write it in pure Ruby, preferably an in-place solution.

相关标签:
22条回答
  • 2020-12-05 07:16
    def reverse(string)
      result = ""
      idx = string.length - 1
      while idx >= 0
      result << string [idx]
      idx = idx - 1
     end
    
     result
    
    end 
    
    0 讨论(0)
  • 2020-12-05 07:16

    I believe this would work also

    def reverse(str)
      string = ''
       (0..str.size-1).each do |i|
        string << str[str.size - 1 - i]
       end
      string
    end
    
    0 讨论(0)
  • 2020-12-05 07:16

    If you have sentence "The greatest victory is that" and you want to have "that is victory greatest The" you should to use this method

    def solution(sentance)
      sentance.split.reverse.join(" ")
    end
    
    solution("The greatest victory is that")
    
    0 讨论(0)
  • 2020-12-05 07:17

    Here is a simple alternative, it first breaks the string into an array, counts the length and subtracts one(because of ruby's indexing rule for array starting from 0), creates an empty variable, then runs an iteration on the keys of the array whilst appending the value of the array length minus current array index to the empty variable created and when it reaches the zeroth(sorry for my french) value it stops. Hope this helps.

    class String
       def rString
           arr = self.split("")
           len = arr.count - 1
           final = ""
           arr.each_index do |i|
               final += arr[len - i]
           end
           final
      end
    end
    
    0 讨论(0)
  • 2020-12-05 07:19
    str = "something"
    reverse = ""
    str.length.times do |i|
      reverse.insert(i, str[-1-i].chr)
    end
    
    0 讨论(0)
  • 2020-12-05 07:20

    Just for discussion, with that many alternates, it is good to see if there are major differences in speed/efficiency. I cleaned up the code a bit as the code showing output was repeatedly reversing the outputs.

    # encoding: utf-8
    
    require "benchmark"
    
    reverse_proc = Proc.new { |reverse_me| reverse_me.chars.inject([]){|r,c| r.unshift c}.join }
    
    class String
      def reverse # !> method redefined; discarding old reverse
        each_char.to_a.reverse.join
      end
    
      def reverse! # !> method redefined; discarding old reverse!
        replace reverse
      end
    
      def reverse_inplace!
        half_length = self.length / 2
        half_length.times {|i| self[i], self[-i-1] = self[-i-1], self[i] }
      end
    
    end
    
    def reverse(a)
      (0...(a.length/2)).each {|i| a[i], a[a.length-i-1]=a[a.length-i-1], a[i]}
      return a
    end
    
    def reverse_string(string) # method reverse_string with parameter 'string'
      loop = string.length       # int loop is equal to the string's length
      word = ''                  # this is what we will use to output the reversed word
      while loop > 0             # while loop is greater than 0, subtract loop by 1 and add the string's index of loop to 'word'
        loop -= 1                  # subtract 1 from loop
        word += string[loop]       # add the index with the int loop to word
      end                        # end while loop
      return word                # return the reversed word
    end                        # end the method
    
    lorum = <<EOT
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent quis magna eu
    lacus pulvinar vestibulum ut ac ante. Lorem ipsum dolor sit amet, consectetur
    adipiscing elit. Suspendisse et pretium orci. Phasellus congue iaculis
    sollicitudin. Morbi in sapien mi, eget faucibus ipsum. Praesent pulvinar nibh
    vitae sapien congue scelerisque. Aliquam sed aliquet velit. Praesent vulputate
    facilisis dolor id ultricies. Phasellus ipsum justo, eleifend vel pretium nec,
    pulvinar a justo. Phasellus erat velit, porta sit amet molestie non,
    pellentesque a urna. Etiam at arcu lorem, non gravida leo. Suspendisse eu leo
    nibh. Mauris ut diam eu lorem fringilla commodo. Aliquam at augue velit, id
    viverra nunc.
    EOT
    

    And the results:

    RUBY_VERSION # => "1.9.2"
    
    name = "Marc-André"; reverse_proc.call(name) # => "érdnA-craM"
    name = "Marc-André"; name.reverse! # => "érdnA-craM"
    name = "Marc-André"; name.chars.inject([]){|s, c| s.unshift(c)}.join # => "érdnA-craM"
    name = "Marc-André"; name.reverse_inplace!; name # => "érdnA-craM"
    name = "Marc-André"; reverse(name) # => "érdnA-craM"
    name = "Marc-André"; reverse_string(name) # => "érdnA-craM"
    
    n = 5_000
    Benchmark.bm(7) do |x|
      x.report("1:") { n.times do; reverse_proc.call(lorum); end }
      x.report("2:") { n.times do; lorum.reverse!; end }
      x.report("3:") { n.times do; lorum.chars.inject([]){|s, c| s.unshift(c)}.join; end }
      x.report("4:") { n.times do; lorum.reverse_inplace!; end }
      x.report("5:") { n.times do; reverse(lorum); end }
      x.report("6:") { n.times do; reverse_string(lorum); end }
    end
    
    # >>              user     system      total        real
    # >> 1:       4.540000   0.000000   4.540000 (  4.539138)
    # >> 2:       2.080000   0.010000   2.090000 (  2.084456)
    # >> 3:       4.530000   0.010000   4.540000 (  4.532124)
    # >> 4:       7.010000   0.000000   7.010000 (  7.015833)
    # >> 5:       5.660000   0.010000   5.670000 (  5.665812)
    # >> 6:       3.990000   0.030000   4.020000 (  4.021468)
    

    It's interesting to me that the "C" version ("reverse_string()") is the fastest pure-Ruby version. #2 ("reverse!") is fastest but it's taking advantage of the [].reverse, which is in C.

    • Edit by Marc-André Lafortune *

    Adding an extra test case (7):

    def alt_reverse(string)
      word = ""
      chars = string.each_char.to_a
      chars.size.times{word << chars.pop}
      word
    end
    

    If the string is longer (lorum *= 10, n/=10), we can see that the difference widens because some functions are in O(n^2) while others (mine :-) are O(n):

                 user     system      total        real
    1:      10.500000   0.030000  10.530000 ( 10.524751)
    2:       0.960000   0.000000   0.960000 (  0.954972)
    3:      10.630000   0.080000  10.710000 ( 10.721388)
    4:       6.210000   0.060000   6.270000 (  6.277207)
    5:       4.210000   0.070000   4.280000 (  4.268857)
    6:      10.470000   3.540000  14.010000 ( 15.012420)
    7:       1.600000   0.010000   1.610000 (  1.601219)
    
    0 讨论(0)
提交回复
热议问题