NoMethodError while adding node in Ruby - ruby

I am trying to print a linked list in ruby but getting the error add': undefined method `next=' for #<Node:0x000001c5c0738688 #data=1, #next=nil> (NoMethodError)
any idea what i should do ?
class Node
def initialize data
#data = data
#next = nil
end
end
class LinkedList
def initialize
#head = nil
end
def add data
temp = #head
#head = Node.new(data)
#head.next = temp
end
def printList
temp = #head
while temp
puts temp.data
temp = temp.next
end
end
end
list = LinkedList.new
list.add(1)
list.add(2)
list.add(3)
list.printList()

In order to access the setter for the next attribute I'd propose adding an attribute_accessor to Node.
class Node
attr_accessor :next
def initialize(data)
#data = data
end
end
This will generate both a setter and a getter for the next attribute within your Node instance.
Additionally I would also add an attr_reader to Node so that you can access data from outside of the instance.
class Node
attr_accessor :next
attr_reader :data
def initialize(data)
#data = data
end
end

Related

Accessing instance variables from outside the class

I'm having issues understanding this encapsulation. I have instance variables defined with attr_accessor. I'm trying to access them outside class. But they are always nil and returns undefined method.
NoMethodError: undefined method `has_key?' for nil:NilClass
Please help me understand.
class TrieNode
attr_reader :value, :next, :children
def initalize
#value = nil
#children = Hash.new
#next = nil
end
end
class Trie
attr_accessor :root
def initialize
#root = TrieNode.new
end
def build_trie(strs)
cur = #root
strs.each do |str|
str.chars.each do |char|
if cur.children.has_key? char
cur = cur.children[char]
next
else
new_node = TrieNode.new
cur.children[char] = new_node
cur = new_node
end
end
cur = #root
end
end
end
Yes, it is not encapsulation, it is because your object is not instantiated properly, which is caused by a typo
def initalize
#value = nil
#children = Hash.new
#next = nil
end
should be initialize not initalize

Linked List ruby, the Node and LInkedlist class doesnt work properly

I have some issues with this code, so, I'm trying to make a linked list but with the first variable I get the next issue:
nodo.rb:34 in 'initialize': wrong number of arguments(1 for 0)
So, the Node class have the actual node and the link, and LinkedList the size and the header.
The problem comes when I try to add a new value but I receive the issue. So I dont know how to fix this problem. I will receive any help you could give me.
class Node
def intialize(data,ref = nil)
#data = data
#refe = refe
end
def get_data
return #data
end
def set_data(newdata)
#dato = newdata
end
def get_ref
return #ref
end
def set_ref(newref)
#ref = newref
end
end
class Linkedlist
def initialize
#size = 0
#header = nil
end
def add_var(value)
#aize = #size + 1
if #header == nil
#header = Node.new(value) #the issue comes here, in the moment when I try to make a new class of Node
else
nodeActual = #header
while nodeActual.get_ref != nil
nodeActual = nodeActual.get_ref
end
nodeActual.set_ref(Node.new(value))
end
end
#def print_list
#end
def get_size
return #size
end
end
list = Linkedlist.new
stop = nil
while stop != -1
a = gets.chomp
if a.to_i == -1
stop = -1
else
list.add_var(a)
end
end
#list.print_list
you have a typo in Node class, rename intialize to initialize (missing i)

inserting in linked lists with ruby

Hi I'm trying to insert a value at a specific index in a linked list in ruby.
Here is my code thus far:
class Node
attr_accessor :data, :pointer, :next
def initialize(data, pointer = nil)
#data = data
#pointer = pointer
end
def next
#data = #pointer
end
end
class LinkedList
attr_accessor :head, :data, :pointer
def initialize(data)
#head = Node.new(data, pointer)
end
def index_at(value_of_index)
current = head
value_of_index.times do
if current.pointer == nil
current = Node.new(nil, nil)
return current = current.data
else
current = current.next
end
end
current.data
end
def insert_at_index(index, value)
current = head
index.times do
current.next
end
current = Node.new(value)
end
end
The problem I've having is with the def insert_at_index method... I can't seem to figure out how to place the new node at the index and value. Any help you can give me would be greatly appreciated.
Say your linked list looks like this:
a -> b -> d -> e
To insert c into the 3rd index, you would move to the second index to get b, create a new node, set b's next to the new node c, and set c's next to the old third index item, d.
This will give you:
a -> b -> c -> d -> e
That said, the code should look like this:
def insert_at_index(index, value)
current = head
# make current b. You may want to put this in a function node_at_index
(index - 1).times do
raise "List not long enough" if current.nil?
current = current.next
end
new_node = Node.new(value) # new node c
new_node.next = current.next # c's next is b's next, d
current.next = new_node # b's next is c
end
From the looks of it there seem to be other issues with your code as well. You're overwriting #data in your next function (you probably meant to just return #pointer), LinkedList#initialize doesn't have pointer defined, etc
You could simplify your Node to look like this:
class Node
attr_accessor :data, :next
def initialize(data, next=nil)
#data = data
#next = next
end
end
Which should work for you.
Here is one solution that worked for me:
class Node
attr_accessor :data, :pointer
alias_method :next, :pointer
def initialize(data, pointer = nil)
#data = data
#pointer = pointer
end
def next
#pointer
end
end
class LinkedList
attr_accessor :head, :data, :pointer
def initialize(data)
#head = Node.new(data, pointer)
end
def index_at(value_of_index)
current = head
value_of_index.times do
if current.pointer == nil
current = Node.new(nil, nil)
return current = current.data
else
current = current.next
end
end
current.data
end
def insert_at_index(index, value)
current = head
(index - 1).times do
if current.pointer != nil
current = current.next
end
end
new_node = Node.new(value)
if current.pointer != nil
new_node.pointer = current.pointer
end
current.pointer = new_node
end
end

Singly linked list in Ruby using part of code

I got a question for implementation methods like get_item(index), or find(value) with used classes.
class SinglyLinkedListItem
attr_accessor :object, :next
attr_reader :list
def initialize(object, list)
#object = object
#list = list
end
end
class SinglyLinkedList
attr_reader :length
def initialize
#length = 0
#head = nil
#tail = nil
end
got some methods like
def each
if #length > 0
item = #head
begin
yield item.object
item = item.next
end until item.nil?
end
end
I tried with many ways, but im still getting this error:
NoMethodError: undefined method `object' for nil:NilClass
You have to define method #object on nil:
def nil.object; self end
The error will not appear that way.
I had this problem before with attr_accessor.
Try replacing the
##
with
self.#
And you might want to check the item class as a precaution.
yield item.object unless item.nil?
For Ex:
def each
if self.length > 0
item = self.head
begin
yield item.object unless item.nil? #Check if item turned nil or not
item = item.next
end until item.nil?
end
end
And there might be some more handling that you need to do, but your given data doesn't provide me enough information.

Ruby Singly Linked List Implementation

I'd like to write an exist function that returns true if a value exists as a node in a linkedlist and returns false otherwise. So far, I have the following code which always returns true. Any help is appreciated:
class SinglyLinkedList
attr_accessor :head, :tail, :count
def initialize
#head = nil
#tail = nil
#count = 0
end
def insert_front(value)
node = Node.new(value)
if #head.nil?
#head = node
#tail = node
else
node.next = #head
#head = node
end
#count +=1
end
def print_first()
puts head.data
end
def print_last()
puts tail.data
end
def exist(value)
walker = #head
until walker.nil?
if walker.data == value
return true
end
walker = walker.next
end
false
end
def size()
count
end
end
class Node
attr_accessor :data, :next
def initialize(data)
#next = nil
#data = data
end
end
This is my test code:
list = SinglyLinkedList.new
list.insert_front(1)
list.exist(2)
which returns true.
Before solution just consider that singly linked list can insert only via append to list. You try to insert nodes in wrong direction.
The problem with you code is that you use reserved method name next, just refactor you code and write simple:
class SinglyLinkedList
class Node
attr_reader :value
attr_accessor :pointer
def initialize(value, pointer = nil)
#value = value
#pointer = pointer
#count = 0
end
end
attr_reader :head, :tail
def initialize
#head = nil
#tail = nil
end
def insert(value)
node = Node.new(value)
#count += 1
if #head.nil?
#head = node
#tail = node
else
#tail.pointer = node
#tail = node
end
end
def inspect
return [] unless #head
values = []
node = #head
begin
values << node.value
node = node.pointer
end while node != nil
values
end
def exists?(value)
return false unless #head
node = #head
begin
node = node.pointer
end while node != nil && node.value != value
node.nil?
end
end

Resources