Reassign `this` in Java class - java

I'm just fooling around in Java right now, trying to implement something similar to a stack using linked lists.
class ListStack {
int value;
int size;
ListStack next;
public ListStack (int add) {
this.size = 1;
this.value = add;
this.next = null;
}
public void push (int add) {
this.next = this;
this.value = add;
this.size++;
}
public int pop() {
if (this.size == 0) { throw new EmptyListStackException(); }
int i = this.value;
this = this.next;
this.size--;
return i;
}
public int size() {
return this.size;
}
public int peek() {
return this.value;
}
}
Basically it's an insertion-in-front linked list which also removes from front. NetBeans pops an error when I try to do this = this.next; it says I cannot reassign final value this.
I'd like my final implementation to do something like the below:
ListStack var = new ListStack(5); //var is now 5 -> null
var.push(3); //var is now 3 -> 5 -> null
int val = varr.pop(); //var is now 5 -> null, val == 3
Commenting put that this = this.next code, the rest seems to work.
ListStack a = new ListStack(5);
System.out.println(a.size()); //prints 1
System.out.println(a.peek()); //prints 5
a.push(4);
System.out.println(a.size()); //prints 2
System.out.println(a.peek()); //prints 4
a.push(6);
System.out.println(a.size()); //prints 3
System.out.println(a.peek()); //prints 6
a.push(1);
System.out.println(a.size()); //prints 4
System.out.println(a.peek()); //prints 1
//a is 1 -> 6 -> 4 -> 5 -> null

There is a conceptual error in your code: basically you are not creating any new stack element with your push method.
But the problem is that calling the class listStack becomes misleading, because actually what you want to create are new elements of the stack, so you should create a class node maybe.
Moreover you can't ovveride "this" because it is a java keyword and it always refers to the current object.
To give you a hint of what to do to implement a stack as a linked list you should create class Node with a value field value and a reference to the previous Node (the first node will just have a null pointer) .
In the class ListStackyou should have a reference to the last node and its push() method should create a new Node and set this one as the new last node.

Let me point you in right direction. As others have commented, this stack does not work properly Consider doing something like this:
public class ListStack {
private class Node {
private int value;
private Node next;
//inner class which holds your each element and reference to next
//fill all details required
}
private Node head;
private int size;
public ListStack() {
head = null;
size = 0;
}
public void push(int value) {
Node temp = new Node(value);
if(head == null)
head = temp;
else {
temp.setNext(head); // provide link to already existing stack
head = temp; // bring new element on top
}
}
public int pop() {
if(head==null);
//throw exception
int temp = head.getValue();
head = head.getNext(); //remove element and bring down the stack
return temp;
}
}

Related

Representing each digit of long number as a node of list

I`m implementing a list class of Big numbers (dynamic list) and trying to represent a received long number as a list
for example : 98765432123
will appear as : 9-8-7-6-5-4-3-2-1-2-3 each digit is a node.
list.
using another class with simple methods (IntNode class):
private int _value;
private IntNode node;
public IntNode(int val) {
_value = val;
node = null;
}
public IntNode(int val, IntNode next) {
_value = val;
node = next;
}
public int get_value() {
return _value;
}
public void set_next(IntNode _next) {
this.node = _next;
}
public void set_value(int _value) {
this._value = _value;
}
public IntNode get_next() {
return node;
}
BigDecimal class attributes :
private IntNode _head
Im using a constructor to receive a long num and represent it as a list by adding each digit to a node.
but having a NullPointerException when trying to add new digit to next node because next node is null.
any help of how to do it without using arrayslist hashmaps etc.. would be appreciated!!
here`s my code where i get nullPointerException error by adding each digit to seperate node.:
public BigDecimalNum(long num) {
_head=new IntNode((int)num%10); // set node to first digit
while(num>0) {
_head.get_next().set_value((int)num % 10); // set next node to next digit.
num/=10;
}
A simple way would be using a string representation of the number:
long num = 98765432123L;
String numStr= String.valueOf(num);
System.out.println(numStr);
String[] arr = numStr.split("");
String lst = String.join("-",arr);
System.out.print(lst);
which gives the ouput:
98765432123
9-8-7-6-5-4-3-2-1-2-3
I modified your IntNode class to simplify the example.
BigDecimalNum bd = new BigDecimalNum(12345l);
System.out.println(bd);
Prints
1-2-3-4-5
the BigDecimalNum constructor basically iterates over the long value and adds the digit to the linked list.
Since you want the head to point to the high order digit, the linked list is constructed backwards, with the head changing each time.
It is then corrected by repositioning to the first valid node.
class BigDecimalNum {
IntNode _head = new IntNode();
public BigDecimalNum(long num) {
while(num > 0) {
_head = _head.addNode((int)(num % 10));
num/=10;
}
_head = _head.next;
}
class IntNode {
private int _value;
private IntNode next;
public IntNode() {
}
adds a new value and returns the next node after adjusting the
new node to set next to the previous one.
public IntNode addNode(int val) {
_value = val;
IntNode t = new IntNode();
t.next = this;
return t;
}
}
I also added a toString method to the BigDecimalNum class to display the linked list. Since you only have a single BigDecimalNum constructor that must take a long it was not necessary to check if the head was null.
public String toString() {
StringBuilder sb = new StringBuilder().append(_head._value);
IntNode start = _head.next;
while(start != null) {
sb.append("-").append(start._value);
start = start.next;
}
return sb.toString();
}
}
Maybe you can construct a new object of IntNode and use the set_next() method. You should also update the "_head" in each loop. Otherwise you would always update the second entry in the list. I came up with this code:
public static IntNode BigDecimalNum(long num) {
IntNode _head = new IntNode((int)num%10); // set node to first digit
num/=10; // go to second digit
IntNode digit = _head;
while (num>0) {
IntNode nextDigit = new IntNode((int)num % 10);
digit.set_next(nextDigit); // set next node to next digit.
num/=10;
digit = nextDigit;
}
return _head;
}

We are trying to find the minimum of a linked list

We are practicing for an exam and are trying to find the minimum value of a linked list in java. This algorithm keeps returning the last element of the list instead of the minimum.
public class minMax {
element head;
public void MinMax(){
this.head = null;
}
public void addElement(element el){
element reference = this.head;
this.head = el;
element nxt = this.head.getNext();
nxt= reference;
}
public int findMin(){
int min = this.head.getValue();
element current = this.head;
while (current != null) {
if(current.getValue() < min){
System.out.println("found min");
min = current.getValue();
}
current = current.getNext();
}
return min;
}
public static void main(String[] args) {
element a = new element(5,null);
element b = new element(55, null);
element c = new element(45, null);
minMax list= new minMax();
list.addElement(a);
list.addElement(b);
list.addElement(c);
int min = list.findMin();
System.out.println(min);
}
}
The main problem is with this part:
element nxt = this.head.getNext();
nxt= reference;
This doesn't change the value of next inside head in the way that you're expecting. It just makes the nxt variable refer to reference.
You haven't included the code for your Element class, but you probably want to update next directly e.g.
this.head.setNext(reference);
Also this line:
public void MinMax() {
is not defining a constructor for your class, as you're probably expecting it to because the case of the name MinMax is different to the name of the class minMax. A constructor also doesn't have a return type so to fix this rename your class MinMax (to follow Java naming conventions) and then remove the void from the constructor definition.
Based on your demo, I just tested it locally and make some modifications.
Using Comparable to enable you to replace the type easily as long as the type implemented the Comparable interface (to find the minimum, you have to compare);
Using head as the sentry to make the adding and deleting (if you need to delete) easier;
By the way, in java you'd better use Uppercase prefix for the class name, so your class name element should be replace by Element. And actually you are encapsulating your class in a good way as a beginner.
Here is the code:
public class HelloWorld {
Node head; // not store any value, just used to link the nodes;
public Comparable findMin() {
if (head == null || head.next == null) {
return null;
}
Comparable min = head.next.value;
Node p = head.next.next;
while(p != null) {
if (min.compareTo(p.value) > 0) min = p.value;
p = p.next;
}
return min;
}
public void add(Node node) {
if (head == null) {
head = new Node(null, node);
} else {
node.next = head.next;
head.next = node;
}
}
public static void main(String... args) {
HelloWorld list = new HelloWorld();
list.add(new Node(5, null));
list.add(new Node(45, null));
list.add(new Node(55, null));
System.out.println(list.findMin().toString());
}
static class Node {
Comparable value;
Node next;
public Node(Comparable theValue, Node theNext) {
this.value = theValue;
this.next = theNext;
}
}
}
The output is working as you expect.
5
Hope it helps you ~

Trouble searching a Stack in Java

I'm having trouble with programming a function in Java.
First i have implemented a Stack through a Single Linked List, like this:
public class ListStack<E> implements Stack<E> {
private static class Node<T> {
private T item;
private Node<T> next;
private Node(T item, Node<T> next) {
this.item = item;
this.next = next;
}
}
private Node<E> first;
private int size;
public ListStack() {
this.size = 0;
this.first = null;
}
#Override
public E peek() {
return first.item;
}
#Override
public void pop() {
first = first.next;
size--;
}
#Override
public void push(E e) {
Node<E> node = new Node<E>(e, first);
first = node;
size++;
}
#Override
public boolean isEmpty() {
return (first == null);
}
#Override
public int size() {
return size;
}
#Override
public Stack<E> reverse(){
ListStack<E> reversed = new ListStack<E>();
Node<E> node = first;
while(node != null){
reversed.push(node.item);
node = node.next;
}
return reversed;
}
}
Then i have created a stackof a type X. Here's that type's definition and constructor:
private String first, second;
private ListStack<String> text;
public X(String first, String second){
this.first = first;
this.second = second;
this.text = new ListStack<String>();
}
There are getters for both the strings firstand second, getFirst(), and getSecond(), respectively.
Then i want to write a function that basically, for each X of the stack, checks if the String second is equal to the String txt, passed as the function's argument. If it is, it returns X and deletes the Node from the stack, otherwise just returns null.
Here's my implementation of the method:
First, as a private attribute of the class:
private Stack<X> text; //for simplicity, let's assume the stack already contains values of type `X`.
Then:
private X getX(String txt) {
Stack<X> stack = text.reverse();
Stack<X> stack_final = new ListStack<X>();
X c;
String txt2;
boolean found = false;
for (int i = 0; i < stack.size() && !found; i++) {
c = stack.peek(); //extracts the element
txt2 = c.getSecond(); //gets the name
if (txt2.equals(txt)) {
found = true;
stack.pop();
} else
stack_final.push(c);
stack.pop();
}
if (found) {
text = stack_final;
return c;
}
else
return null;
}
What am i doing wrong ?
My guess is that i'm not updating the final stack correctly, with only the values that don't check, but i'm not sure it is that...
The main problem is the for-loop. Just step through it in your head:
i=0 stack=[1,2,3,4,5,6] stack_size=6
i=1 stack=[2,3,4,5,6] stack_size=5
i=2 stack=[3,4,5,6] stack_size=4
i=3 stack=[4,5,6] stack_size=3
the code actually breaks off after reading only half of the stack. You should rather use isEmpty() than a counter.
private X getX(String txt){
Stack<X> stack = text.reverse();
Stack<X> stack_final = new ListStack<X>();
X c = null;
while(!stack.isEmpty()){//transfer all items from stack to stack_final
//retrive and remove the first item from stack
X x = stack.peek();
stack.pop();
if(x.getSecond().equals(txt))//save x as searched item, if it matches
c = x;
//add the item to stack_final
stack_final.push(x);
}
//save stack_final as text (stack_final is a copy of text)
text = stack_final;
//c is either the searched item, or null, if no item was found
return c;
}
And btw., it's common that pop() returns the removed element.
public X pop(){
X res = first.item;
first = first.next;
return res;
}
You will get a NullPointerException if you try to peek() or pop() an empty stack!
public E peek() {
return first.item; // first is null if stack is empty!
}
public void pop() {
first = first.next; // first is null if stack is empty!
size--;
}
The Java Stack class throws an EmptyStackException in those cases.
Then I want to write a function that basically, for each X of the stack, checks if the String second is equal to the String txt, passed as the function's argument. If it is, it returns X and deletes the Node from the stack, otherwise just returns null.
Now, to achieve what you asked, you can simply do:
Stack<X> stack = text.reversed();
X elementFound = null;
while (!stack.isEmpty()) {
if (txt.equals(stack.peek().getSecond()) {
elementFound = stack.peek();
} else {
stackCopy.push(stack.peek());
}
stack.pop();
}
// now stack is empty and stackCopy contains stack reversed and without
// elementFound, if elementFound is not null (meaning it was found)
text = stackCopy; // stack was text reversed
return elementFound;

Recursively add a node at a certain index on Linked List

I'm trying to add a list node at a specified index recursively. By that I mean the List class addAtRec() calls addAtRec() in the ListNode class, that method is supposed to be recursive.
This is what I did:
List:
public class List implements Cloneable {
private ListNode firstNode;
private ListNode lastNode;
private String name;
private int counter;
public List(){
this("list");
}
public void addAtRec(Object obj, int k)
{
if(firstNode != null)
firstNode.addAtRec(obj, k, firstNode);
}
}
That's of course only the relevant parts...
ListNode:
public class ListNode implements Cloneable {
Object data;
ListNode nextNode;
public ListNode(Object o){
this(o,null);
}
public ListNode(Object o,ListNode node){
data=o;
nextNode=node;
}
public void addAtRec(Object obj, int k, ListNode current) throws ListIndexOutOfBoundsException {
if(current.nextNode == null && k != 0)
throw new ListIndexOutOfBoundsException(); //line 47
if(k == 0)
{
ListNode l = new ListNode(obj);
l.nextNode = current.nextNode;
current.nextNode = l;
}
current = current.nextNode;
addAtRec(obj, k, current); //line 55
k--;
}
ListIndexOutOfBoundsException:
public class ListIndexOutOfBoundsException extends RuntimeException {
}
my main() method:
String s1 = "Objects";
String s2 = "to";
String s3 = "check";
String s4 = "are";
String s5 = "strings";
List list = new List("My list");
list.insertAtBack(s1);
list.insertAtBack(s2);
list.insertAtBack(s3);
list.insertAtBack(s4);
list.insertAtBack(s5);
list.addAtRec(s3, 2);
and the error:
Exception in thread "main" ListIndexOutOfBoundsException
at ListNode.addAtRec(ListNode.java:47)
at ListNode.addAtRec(ListNode.java:55)
at ListNode.addAtRec(ListNode.java:55)
at ListNode.addAtRec(ListNode.java:55)
at ListNode.addAtRec(ListNode.java:55)
at List.addAtRec(List.java:158)
What did I do wrong?
Thanks for your time and answers.
You have two errors in your recursive method:
Before calling addAtRec(obj, k, current); you should decrease k by 1, so it would be better to call k-- before this line.
Once you have reached the base case (when k == 0)and executed the logic to add the new node, your recursive method must stop, probably with a simple return; statement. In this case, you're not stopping it so you will call it every time until get to the end of your list.
Based on these 2 advices, your code should look like:
public void addAtRec(Object obj, int k, ListNode current)
throws ListIndexOutOfBoundsException {
//always use braces even for single line block of code
if(current.nextNode == null && k != 0) {
throw new ListIndexOutOfBoundsException();
}
if(k == 0) {
ListNode l = new ListNode(obj);
l.nextNode = current.nextNode;
current.nextNode = l;
//stopping the recursion
return;
}
current = current.nextNode;
//decrease k by 1 before calling your method recursively
k--;
addAtRec(obj, k, current);
}
This is not part of the main problem, but IMO your methods to add nodes in the list should belong to the List class and not to theListNode. Remember that the data structure that holds the nodes and decide how to tie them will be the List, not the nodes by themselves.

Regarding finding the middle element of linked list

I am following the below approach to calculate the middle element from the linked list , but I want is there any built in method or any other approach which can also find the same easily , the approach that I am following is shown bellow..
import test.LinkedList.Node;
public class LinkedListTest {
public static void main(String args[]) {
//creating LinkedList with 5 elements including head
LinkedList linkedList = new LinkedList();
LinkedList.Node head = linkedList.head();
linkedList.add( new LinkedList.Node("1"));
linkedList.add( new LinkedList.Node("2"));
linkedList.add( new LinkedList.Node("3"));
linkedList.add( new LinkedList.Node("4"));
//finding middle element of LinkedList in single pass
LinkedList.Node current = head;
int length = 0;
LinkedList.Node middle = head;
while(current.next() != null){
length++;
if(length%2 ==0){
middle = middle.next();
}
current = current.next();
}
if(length%2 == 1){
middle = middle.next();
}
System.out.println("length of LinkedList: " + length);
System.out.println("middle element of LinkedList : " + middle);
}
}
class LinkedList{
private Node head;
private Node tail;
public LinkedList(){
this.head = new Node("head");
tail = head;
}
public Node head(){
return head;
}
public void add(Node node){
tail.next = node;
tail = node;
}
public static class Node{
private Node next;
private String data;
public Node(String data){
this.data = data;
}
public String data() {
return data;
}
public void setData(String data) {
this.data = data;
}
public Node next() {
return next;
}
public void setNext(Node next) {
this.next = next;
}
public String toString(){
return this.data;
}
}
}
Output:-
length of LinkedList: 4
middle element of LinkedList : 2
The basic algorithm would be
Take two pointers
Make both pointing to first node
Increment first with two nodes and second with one, at a time.
Loop until the 1st loop reaches the end. At this point, the 2nd will be at the middle.
Example:-
while ( p2.next != null ) {
p2 = p2.next;
if (p2.next != null) {
p2 = p2.next;
p1 = p1.next;
}
}
It will definitely work in odd case, for even case you need to check one more condition if first point is allowed to move next but not next to next then both pointers will be at middle you need to decide which to take as middle.
I would recommend using the Java built in
LinkedList<Object e>
It gives you all the functionality you need like getting the length: list.size(), and the middle object:
list.get((list.size())/2);
Options:
Have a double linked-list and go from the back and front at the same time until you get to a common point.
Store the size of the list and simply stop when you've reached this half this size (similar to what the standard API's LinkedList does).
Other than that I don't think you can do better than your algorithm.
public Node getMiddleElement(Node head) {
Node slow_pointer=head;
Node fast_pointer=head;
while(fast_pointer.next!=null && fast_pointer.next.next!=null)
{
slow_pointer=slow_pointer.next;
fast_pointer=fast_pointer.next.next;
}
return slow_pointer;
}
Node mid_elem=PrintMiddleElement(head);
System.out.println(mid_elem.data);
I/P:5 10 15 25 35 25 40 O/P:25
Solution for this question:
Use two indexes, first and second, both initialized to 0
Increment first by 1 and second by 2 * first
Set value of first to middle
Loop will execute until value of second is less than list size
Here is code snippet for getting middle element of list or linked list:
private int getMiddle(LinkedList<String> list) {
int middle = 0;
int size = list.size();
for (int i = 0, j = 0; j < size; j = i * 2) {
middle = i++;
}
return middle;
}
LinkedList<String> list = new LinkedList<>();
list.add("1");
list.add("2");
list.add("3");
list.add("4");
list.add("5");
list.add("6");
list.add("7");
int middle = getMiddle(list);
System.out.println(list.get(middle));

Categories