<< Оператор добавления строки в список Acting Strange — Ruby

Я пытаюсь добавить строку (состоящую из символов из другой строки, повторяемой через цикл 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
Структурированный массив Numpy
Структурированный массив Numpy
Однако в реальных проектах я чаще всего имею дело со списками, состоящими из нескольких типов данных. Как мы можем использовать массивы numpy, чтобы...
T - 1Bits: Генерация последовательного массива
T - 1Bits: Генерация последовательного массива
По мере того, как мы пишем все больше кода, мы привыкаем к определенным способам действий. То тут, то там мы находим код, который заставляет нас...
Что такое деструктуризация массива в JavaScript?
Что такое деструктуризация массива в JavaScript?
Деструктуризация позволяет распаковывать значения из массивов и добавлять их в отдельные переменные.
0
0
58
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Этот:

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, следовательно, видит обновленную версию.

Другие вопросы по теме