Reputation: 137
I'm trying to append a string (made up of characters from another string iterated through a for loop) to an array. But for some reason when I output the items of the array in the end they're all off.
Here's my output for the code I have:
r
racecar
a
aceca
c
cec
e
c
a
r
Final list:
racecar
racecar
acecar
acecar
cecar
cecar
ecar
car
ar
r
I tried adding a empty string to the end of my statement like so,
list << string_current + ""
and it seems to fix the problem. Does anyone know why this is?
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")
I thought that the items in my final list should be idential to those being put into the list during.
list << string_current
Upvotes: 0
Views: 64
Reputation: 22217
You could also have fixed it by
list << string_current.dup
but the real problem is your
string_current << s[j]
Try out (for instance in irb) the following example:
list=[]
str='ab'
list << str
str << 'x'
puts list
You will see that the list contains now 'abx'
, not 'ab'
.
The reason is that the list contains an object reference (pointer) to the string, and when you do the str << 'x'
, you don't create a new object, but modify the existing one, and list
hence sees the updated version.
Upvotes: 0
Reputation: 434665
This:
string_current << s[j]
modifies the string in-place. That means that this:
list << string_current
can put a correct string into list
and then that string can be modified later.
When you append your blank string:
list << string_current + ""
you're creating a brand new string (string_current + ""
) and then pushing that new string onto list
so you're doing this:
tmp = string_current + ""
list << tmp
A couple simple ways around your problem would be explicitly dup'ing the string:
if is_palindrome(string_current)
counter += 1
puts string_current
list << string_current.dup # <--------------------
end
or using +=
instead of <<
on string_current
:
for i in (0...n)
string_current = ''
for j in (i...n)
string_current += s[j]
You should also consider replacing your for
loops (which are rare in Ruby) with methods from Enumerable
. I don't want to go down a refactoring rabbit hole right now so I'll leave that as an exercise for the reader.
Upvotes: 3