strange array behaviour?
I've been practicing coding some algorithms (job interview time), and was coding the Huffman compression algorithm and ran into what seems like strange behaviour in the Ruby array class.
Once I have a built my heap I do a preorder traversal of my tree and store the symbols and binary values in a hash table. Here's the method.
def encode(huffman_tree, encoded_chars, binary)
if huffman_tree.is_leaf?
encoded_chars[huffman_tree.symbol] = binary
else
encode(huffman_tree.left, encoded_chars, binary + '0')
encode(huffman_tree.right, encoded_chars, binary + '1')
end
end
This works fine, but I had previously been passing in an empty array as the binary param and then appending to that array
def encode(huffman_tree, encoded_chars, binary)
if huffman_tree.is_leaf?
encoded_chars[huffman_tree.symbol] = binary
else
encode(huffman_tree.left, encoded_chars, binary << 0)
encode(huffman_tree.right, encoded_chars, binary << 1)
end
end
I'll grant you that it makes more sense to just use a string, but I thought I should be able to do the same thing with an array. However, when I ran the algorithm with binary as an array every recursive call to encode led to the binary array growing in size (I thought it should go out of scope every time the method returns) Here's sample output run with binary as a string and then as an array. Can someone explain why this happens?
string
00000,
00001,
0001,
001,
01000,
01001,
0101000,
01010010
arr开发者_StackOverfloway
00000,
000001,
0000011,
00000111,
000001111000,
0000011110001,
00000111100011000,
0000011110001100010
You're misunderstanding how the operators work in this case:
string = 'test'
# => 'test'
string + 'string'
# => 'teststring'
string
# => 'test'
string << 'string'
# => 'teststring'
string
# => 'teststring'
The String +
method returns a new string representing the combined values. The Array <<
operator appends something to the array, it does not create a new copy.
What you probably want is:
binary + [ 0 ]
This will create a new array, but it isn't especially efficient.
It is important to remember that variables in Ruby represent references to Objects, and that any value passed in as an argument to something is a shared reference. Other languages will implicitly duplicate all arguments to avoid this problem unless you use a pointer or some other kind of explicit reference.
In other words, the array passed in to the method is identical to the array received by the method, so any modifications to it persist outside the scope of the method.
精彩评论