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.
def reverse(string)
result = ""
idx = string.length - 1
while idx >= 0
result << string [idx]
idx = idx - 1
end
result
end
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
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")
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
str = "something"
reverse = ""
str.length.times do |i|
reverse.insert(i, str[-1-i].chr)
end
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.
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)