Я пытаюсь добавить строку (состоящую из символов из другой строки, повторяемой через цикл for) в массив. Но по какой-то причине, когда я вывожу элементы массива, в конце они все выключены.
Вот мой вывод для кода, который у меня есть:
r
racecar
a
aceca
c
cec
e
c
a
r
Final list:
racecar
racecar
acecar
acecar
cecar
cecar
ecar
car
ar
r
Я попытался добавить пустую строку в конец моего оператора, например:
list << string_current + ""
и, кажется, решить проблему. Кто-нибудь знает, почему это так?
def longest_palindrome(s)
n = s.length
max_string = ""
max_string_current = ""
string_current = ""
list = []
counter = 0
for i in (0...n)
for j in (i...n)
string_current << s[j]
# puts "string_current: #{string_current}"
if is_palindrome(string_current)
counter += 1
puts string_current
list << string_current
end
end
string_current = ""
end
puts "Final list:"
list.each do |item|
puts "#{item}"
end
end
def is_palindrome(string)
for i in (0..string.length/2)
if string[i] != string[string.length-1-i]
return false
end
end
return true
end
longest_palindrome("racecar")
Я думал, что элементы в моем окончательном списке должны быть идентичны тем, которые были помещены в список во время.
list << string_current



Этот:
string_current << s[j]
изменяет строку на месте. Это означает, что это:
list << string_current
может поместить правильную строку в list, а затем эту строку можно изменить позже.
Когда вы добавляете пустую строку:
list << string_current + ""
вы создаете совершенно новую строку (string_current + ""), а затем вставляете эту новую строку в list, поэтому вы делаете это:
tmp = string_current + ""
list << tmp
Пара простых способов обойти вашу проблему будет явно дублировать строку:
if is_palindrome(string_current)
counter += 1
puts string_current
list << string_current.dup # <--------------------
end
или используя += вместо << на string_current:
for i in (0...n)
string_current = ''
for j in (i...n)
string_current += s[j]
Вам также следует подумать о замене циклов for (которые редко встречаются в Ruby) методами из Enumerable. Я не хочу сейчас лезть в кроличью нору рефакторинга, поэтому оставлю это в качестве упражнения для читателя.
Вы также могли бы исправить это с помощью
list << string_current.dup
но настоящая проблема в тебе
string_current << s[j]
Попробуйте (например, в ирб) следующий пример:
list=[]
str='ab'
list << str
str << 'x'
puts list
Вы увидите, что список теперь содержит 'abx', а не 'ab'.
Причина в том, что список содержит ссылку на объект (указатель) на строку, и когда вы делаете str << 'x', вы не создаете новый объект, а модифицируете существующий, и list, следовательно, видит обновленную версию.