Как Вы инвертируете строку в Ruby? Я знаю о string#reverse. Я интересуюсь пониманием, как записать это в чистом Ruby, предпочтительно оперативное решение.
Трудно читаемый однострочный текст,
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
str = "something"
reverse = ""
str.length.times do |i|
reverse.insert(i, str[-1-i].chr)
end
Вот один из способов сделать это с помощью inject и unshift:
"Hello world".chars.inject([]) { |s, c| s.unshift(c) }.join
Ruby-эквивалент встроенной функции reverse
может выглядеть так:
# encoding: utf-8
class String
def reverse
each_char.to_a.reverse.join
end
def reverse!
replace reverse
end
end
str = "Marc-André"
str.reverse!
str # => "érdnA-craM"
str.reverse # => "Marc-André"
Примечание : это предполагает Ruby 1.9, иначе потребует «backports»
и установит $ KCODE
для UTF-8.
Для решения, не использующего обратный
, можно сделать:
def alt_reverse(string)
word = ""
chars = string.each_char.to_a
chars.size.times{word << chars.pop}
word
end
Примечание: любое решение, использующее []
для доступа к отдельным буквам, будет иметь порядок O (n ^ 2)
; чтобы получить доступ к 1000-й букве, Ruby должен пройти первые 999 один за другим, чтобы проверить наличие многобайтовых символов. Таким образом, важно использовать итератор вроде each_char
для решения в O (n)
.
Еще одной вещи, которую следует избегать, является построение промежуточных значений увеличивающейся длины; использование + =
вместо <<
в alt_reverse
также приведет к решению O (n ^ 2)
вместо O (n)
.
Построение массива с unshift
также приведет к решению O (n ^ 2)
, потому что это подразумевает повторное копирование всех существующих элементов на один индекс выше каждый раз, когда выполняется без сдвига
.
Уже существует обратный метод на месте, называемый «reverse!»:
$ a = "abc"
$ a.reverse!
$ puts a
cba
Если вы хотите сделать это вручную, попробуйте это (но, вероятно, он не будет многобайтовым. -safe, например UTF-8), и он будет медленнее:
class String
def reverse_inplace!
half_length = self.length / 2
half_length.times {|i| self[i], self[-i-1] = self[-i-1], self[i] }
self
end
end
Это меняет местами каждый байт с начала на каждый байт с конца, пока оба индекса не встретятся в центре:
$ a = "abcd"
$ a.reverse_inplace!
$ puts a
dcba
Используйте
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.