I'm making a program that can recursively add Polynomials (represented by Linked Lists) together. But I keep getting a null pointer exception in the line if (p1.data.exp == p2.data.exp) {
I've tried debugging by setting both terms to either one or the other, but I keep getting the error (does this mean that they are both null?). I don't see how this can happen since it should return before getting to this part if they are null.
Does anyone have suggestions?
Main:
public class Polynomial {
private Node poly;
public Polynomial(){
poly = new Node();
}
private Polynomial(Node node){
poly = node;
}
public void addTerm(int coef, int exp){
Term term = new Term(coef, exp);
Node node = new Node(term, null);
Node iterator = poly;
//if the list is empty just add the node
if (poly.next == null){
System.out.println("poly.next is null. adding node to first pos.");
poly.next = node;
return;
}
//if list isn't empty find the appropriate spot for it
while (iterator.next != null){
System.out.println("iterator.next != null...");
if (exp < iterator.next.data.exp){
System.out.println("\texp < iterator.next.data.exp");
node.next = iterator.next;
iterator.next = node;
return;
}
if (exp == iterator.next.data.exp){
System.out.println("\texp == iterator.next.data.exp");
iterator.next.data.coef += coef;
return;
}
iterator = iterator.next;
}
//if we get to this point then the list isn't empty
//and it doesn't fit inside the list, hence it must
//be added to the end of the list
System.out.println("list wasn't empty, didn't fit inside");
iterator.next = node;
return;
}
#Override
public String toString(){
Node iterator = poly;
String out = "";
if (poly.next == null){
return out;
}
while(iterator.next != null){
out += iterator.next.data.coef;
out += "*x^";
out += iterator.next.data.exp;
out += " + ";
iterator = iterator.next;
}
return out.substring(0, out.lastIndexOf('+'));
}
public Polynomial addPolynomial (Polynomial that){
Polynomial ret = new Polynomial();
Polynomial iterator = this;
return new Polynomial(addPolys(this.poly, that.poly));
}
public Node addPolys(Node p1, Node p2) {
// If P1 is null, just use P2
if (p1 == null) {
p1 = p2;
p2 = null;
}
// if P1 is still null, no P2 either so finished
if (p1 == null) return null;
Node ret = new Node();
// if P2 is null now, just one poly remains
if (p2 == null) {
ret.data = p1.data;
p1 = p1.next;
} else {
// do we combine nodes?
if (p1.data.exp == p2.data.exp) {
ret.data = new Term(p1.data.coef + p2.data.coef, p1.data.exp
+ p2.data.exp);
p1 = p1.next;
p2 = p2.next;
} else {
// we just copy a node
// make p1 the bigger exponent
if (p1.data.exp < p2.data.exp) {
Node t = p1;
p1 = p2;
p2 = t;
}
ret.data = p1.data;
p1 = p1.next;
}
}
ret.next = addPolys(p1, p2);
return ret;
}
/*
* Term
*/
private class Term implements Comparable{
int coef;
int exp;
public int getCoef() {
return coef;
}
public void setCoef(int coef) {
this.coef = coef;
}
public int getExp() {
return exp;
}
public void setExp(int exp) {
this.exp = exp;
}
public Term(int coef, int exp) {
this.coef = coef;
this.exp = exp;
}
public int compareTo(Object rhs){
Term that = (Term)rhs;
return this.exp - that.exp;
}
}//end Term
/*
* Node
*/
private class Node{
Term data;
Node next;
public Term getData() {
return data;
}
public void setData(Term data) {
this.data = data;
this.next = null;
}
public Node getNext() {
return next;
}
public void setNext(Node next) {
this.next = next;
}
public Node() {
this.data = null;
this.next = null;
}
public Node(Term data, Node next) {
this.data = data;
this.next = next;
}
}//end Node
}
Test:
public class Polynomials {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
Polynomial p1 = new Polynomial();
Polynomial p2 = new Polynomial();
Polynomial p0 = new Polynomial();
p1.addTerm(1, 2);
p1.addTerm(1, 4);
p1.addTerm(1, 6);
p2.addTerm(1, 1);
p2.addTerm(1, 3);
p2.addTerm(1, 5);
System.out.println("p1 = " + p1.toString());
System.out.println("p2 = " + p2.toString());
System.out.println("Adding p1 to p2...");
p0 = p1.addPolynomial(p2);
System.out.println(p0.toString());
}
}
One of the data fields in the Node object is not initialized. My guess is that this is setting the data to null.
Node node = new Node(term, null);
So any node variable that references that object will throw an exception when you do p1.data.exponent.
in this part
if (p1.data.exp == p2.data.exp)
property 'data' or 'exp' is null.
I'll give an advice write your code more protective:
use getter and setter method;
don't use chain of references (eg, p1.data.exp);
test 'null' case;
add log infromation;
bye
I'd guess that p1.data or p2.data is null, so you can't obtain the exponent from it.
Related
I am working on a project for my Data Structures class that asks me to write a class to implement a linked list of ints.
Use an inner class for the Node.
Include the methods below.
Write a tester to enable you to test all of the methods with whatever data you want in any order.
I have to create a method called "public void addToBack(int item)". This method is meant to "Add an Item to the end of the list" I have my code for this method down below. When I execute this method my list becomes empty. Does someone know what I did wrong and how to fix it?
import java.util.Random;
import java.util.Scanner;
public class LinkedListOfInts {
Node head;
Node tail;
private class Node {
int value;
Node nextNode;
public Node(int value, Node nextNode) {
this.value = value;
this.nextNode = nextNode;
}
}
public LinkedListOfInts(LinkedListOfInts other) {
Node tail = null;
for (Node n = other.head; n != null; n = n.nextNode) {
if (tail == null)
this.head = tail = new Node(n.value, null);
else {
tail.nextNode = new Node(n.value, null);
tail = tail.nextNode;
}
}
}
public LinkedListOfInts(int[] other) {
Node[] nodes = new Node[other.length];
for (int index = 0; index < other.length; index++) {
nodes[index] = new Node(other[index], null);
if (index > 0) {
nodes[index - 1].nextNode = nodes[index];
}
}
head = nodes[0];
}
public LinkedListOfInts(int N, int low, int high) {
Random random = new Random();
for (int i = 0; i < N; i++)
this.addToFront(random.nextInt(high - low) + low);
}
public void addToFront(int x) {
head = new Node(x, head);
}
public void addToBack(int x) {
if (head == null) {
head = new Node(x, head);
return;
}
tail = head;
while (tail.nextNode != null) {
tail = tail.nextNode;
}
tail.nextNode = new Node(x, tail);
}
public String toString() {
String result = "";
for (Node ptr = head; ptr != null; ptr = ptr.nextNode) {
if (!result.isEmpty()) {
result += ", ";
}
result += ptr.value;
}
return "[" + result + "]";
}
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
LinkedListOfInts list = new LinkedListOfInts(10, 1, 20);
boolean done = false;
while (!done) {
System.out.println("1. Add to Back");
System.out.println("2. toString");
switch (input.nextInt()) {
case 1:
System.out.println("Add an Item to the Back of a List.");
list.addToBack(input.nextInt());
break;
case 2:
System.out.println("toString");
System.out.println(list.toString());
break;
}
}
}
}
When you add to the tail the nextNode should point to null
tail.nextNode = new Node(x, null);
At the moment you are having an endless loop
We started learning Lists in school but I don't really understand how they work. As homework we have to write a method add that adds an element at the end of the list. I don't know why, but when I add more nodes, the Lists only saves the first two. I want to know why and what should I change. This is the code (I am not allowed to change anything from the given code. I can only create new methods...)
public class HeadList {
Entry head;
public HeadList() {
head = null;
}
/**
* Appends a new element with value info to the end of this list
* #param info value of the new element
*/
public void add(int info) {
//TODO
Entry node = head;
if (head != null) {
if (node.next == null){
node.next = new Entry(node, null, info);
}
else{
Entry n = node.next;
while(n != null){
n = n.next;
}
node = new Entry(node, null, info);
}
}
else
head = new Entry(null, null, info);
}
#Override
public String toString() {
String out = "[";
if (head != null) {
out += head.elem;
Entry tmp = head.next;
while (tmp != null) {
out = out + "," + tmp.elem;
tmp = tmp.next;
}
}
out += "]";
return out;
}
public static void main(String[] args) {
HeadList l = new HeadList();
l.add(6);
l.add(7);
l.add(8);
l.add(9);
System.out.println("empty list: " + l);
// Test implementation
}
class Entry {
Entry first;
Entry next;
int elem;
public Entry(Entry first, Entry next, int elem) {
this.first = first;
this.next = next;
this.elem = elem;
}
}
}
change your add method to this:
public void add(int info) {
Entry node = head;
if (head != null) {
if (node.next == null){
node.next = new Entry(node, null, info);
}
else{
Entry n = node.next;
while(n != null){
node =n;
n = n.next;
}
Entry next = new Entry(node, null, info);
node.setNext(next);
}
}
else
head = new Entry(null, null, info);
}
also update your Entry class:
class Entry {
Entry first;
Entry next;
int elem;
public Entry(Entry first, Entry next, int elem) {
this.first = first;
this.next = next;
this.elem = elem;
}
public void setNext(Entry next) {
this.next = next;
}
}
public class doubleLinkedList {
class Node {
String value;
Node prev;
Node next;
Node(String val, Node p, Node n) {
value = val;
prev = p;
next = n;
}
Node(String val) {
value = val;
prev = null;
next = null;
}
}
Node first;
Node last;
public doubleLinkedList() {
first = null;
last = null;
}
public boolean isEmpty() {
if (first == null)
return true;
else
return false;
}
/**The size method returns the length of the linked list
* #return the number of element in the linked list
*/
public int size() {
int count = 0;
Node traverse = first;
while (traverse != null) {
count++;
traverse = traverse.next;
}
return count;
}
public void add(String element) {
if (isEmpty()) {
first = new Node(element);
last = first;
} else {
Node p = first;
Node elementTobeAdded;
while (((p.value).compareTo(element)) > 0 && p.next != null) {
p = p.next;
}
if (p.next != null) {
elementTobeAdded = new Node(element, p, p.next);
p.next.prev = elementTobeAdded;
p = elementTobeAdded.prev;
} else {
elementTobeAdded = new Node(element, p, null);
p.next = elementTobeAdded;
elementTobeAdded.next = null;
last = elementTobeAdded;
}
}
}
public void printForward() {
Node printNode = first;
while (printNode != null) {
System.out.print(printNode.value + ", ");
printNode = printNode.next;
}
}
}
public class test {
public static void main(String[] args) {
doubleLinkedList car = new doubleLinkedList();
car.add("Jeep");
car.add("benz");
car.add("Honda");
car.add("Lexus");
car.add("BMW");
car.printForward();
}
}
My add method is trying to add nodes to a list in alphabetical order. My printForward method prints out each element in the list.
In my main method, it prints out "Jeep, benz, Honda, BMW,", which is not in alphabetical order.
Change the not empty case for your add method from this
Node p = first;
Node elementTobeAdded;
while(((p.value).compareTo(element)) > 0 && p.next != null)
{
p = p.next;
}
if(p.next != null)
{
elementTobeAdded = new Node(element,p,p.next);
p.next.prev = elementTobeAdded;
p = elementTobeAdded.prev;
}
else
{
elementTobeAdded = new Node(element, p, null);
p.next = elementTobeAdded;
elementTobeAdded.next = null;
last = elementTobeAdded;
}
to this:
Node p = first;
while (p.value.compareTo(element) < 0 && p.next != null) {
p = p.next;
}
if (p.value.compareTo(element) > 0) {
Node toAdd = new Node(element, p.prev, p);
p.prev = toAdd;
if (toAdd.prev != null) {
toAdd.prev.next = toAdd;
}else {
first = toAdd;
}
}else {
Node toAdd = new Node(element, p, p.next);
p.next = toAdd;
if (toAdd.next != null) {
toAdd.next.prev = toAdd;
}else {
last = toAdd;
}
}
There were many errors here. The biggest one was that you never checked for the case where the new element should be inserted at the beginning of the list. A new element was always inserted after the first element even if it should have come first.
Note that "benz" comes at the end because the String.compareTo method treats capitals as coming before lower case letters.
It is not an a linked list... You wrote some sort of Queue (with optional possibility to make it Dequeue).
About your question - you have an error in your 'add' method - at least you don't check if it is necessary to move head forward. It is possible that you have another bugs, but it is too hard to read such styled sources (please fix your question formatting)...
I need to add two polynomials together using a recursive method.
This is for a past-due assignment (I imagine a similar thing will be on a test).
Main class:
public class Polynomial {
private Node poly;
public Polynomial(){
poly = new Node();
}
private Polynomial(Node node){
poly = node;
}
public void addTerm(int coef, int exp){
Term term = new Term(coef, exp);
Node node = new Node(term, null);
Node iterator = poly;
//if the list is empty just add the node
if (poly.next == null){
System.out.println("poly.next is null. adding node to first pos.");
poly.next = node;
return;
}
//if list isn't empty find the appropriate spot for it
while (iterator.next != null){
System.out.println("iterator.next != null...");
if (exp < iterator.next.data.exp){
System.out.println("\texp < iterator.next.data.exp");
node.next = iterator.next;
iterator.next = node;
return;
}
if (exp == iterator.next.data.exp){
System.out.println("\texp == iterator.next.data.exp");
iterator.next.data.coef += coef;
return;
}
iterator = iterator.next;
}
//if we get to this point then the list isn't empty
//and it doesn't fit inside the list, hence it must
//be added to the end of the list
System.out.println("list wasn't empty, didn't fit inside");
iterator.next = node;
return;
}
#Override
public String toString(){
Node iterator = poly;
String out = "";
if (poly.next == null){
return out;
}
while(iterator.next != null){
out += iterator.next.data.coef;
out += "*x^";
out += iterator.next.data.exp;
out += " + ";
iterator = iterator.next;
}
return out.substring(0, out.lastIndexOf('+'));
}
public Polynomial addPolynomial (Polynomial that){
Polynomial ret = new Polynomial();
Polynomial iterator = this;
return addPolynomial(that, ret, iterator);
}
public Polynomial addPolynomial(Polynomial that, Polynomial ret, Polynomial iterator){
if (iterator.poly.next == null){
return new Polynomial(that.poly);
}
if (that.poly.next == null){
return new Polynomial(iterator.poly);
}
if (iterator.poly.next.data.exp < that.poly.next.data.exp){
ret.addTerm(iterator.poly.next.data.coef, iterator.poly.next.data.exp);
iterator.poly = iterator.poly.next;
return iterator.addPolynomial(that);
}
if (iterator.poly.next.data.exp == that.poly.next.data.exp){
ret.addTerm(iterator.poly.next.data.coef + that.poly.next.data.coef, iterator.poly.next.data.exp);
iterator.poly = iterator.poly.next;
that.poly = that.poly.next;
return iterator.addPolynomial(that);
}
if (iterator.poly.next.data.exp > that.poly.next.data.exp){
ret.addTerm(that.poly.next.data.coef, that.poly.next.data.exp);
that.poly = that.poly.next;
return iterator.addPolynomial(that);
}
return ret;
}
/*
* Term
*/
private class Term implements Comparable{
int coef;
int exp;
public int getCoef() {
return coef;
}
public void setCoef(int coef) {
this.coef = coef;
}
public int getExp() {
return exp;
}
public void setExp(int exp) {
this.exp = exp;
}
public Term(int coef, int exp) {
this.coef = coef;
this.exp = exp;
}
public int compareTo(Object rhs){
Term that = (Term)rhs;
return this.exp - that.exp;
}
}//end Term
/*
* Node
*/
private class Node{
Term data;
Node next;
public Term getData() {
return data;
}
public void setData(Term data) {
this.data = data;
this.next = null;
}
public Node getNext() {
return next;
}
public void setNext(Node next) {
this.next = next;
}
public Node() {
this.data = null;
this.next = null;
}
public Node(Term data, Node next) {
this.data = data;
this.next = next;
}
}//end Node
}
Test Class:
public class Polynomials {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
Polynomial p1 = new Polynomial();
Polynomial p2 = new Polynomial();
Polynomial p0 = new Polynomial();
p1.addTerm(1, 2);
p1.addTerm(1, 4);
p1.addTerm(1, 6);
p2.addTerm(1, 1);
p2.addTerm(1, 3);
p2.addTerm(1, 5);
System.out.println("p1 = " + p1.toString());
System.out.println("p2 = " + p2.toString());
System.out.println("Adding p1 to p2...");
p0 = p1.addPolynomial(p2);
System.out.println(p0.toString());
}
}
Have you considered this way of doing it?
public class Polynomial {
public static void main(String[] args) {
Polynomial p1 = new Polynomial();
Polynomial p2 = new Polynomial();
Polynomial p0 = new Polynomial();
p1.addTerm(1, 2);
p1.addTerm(1, 4);
p1.addTerm(1, 6);
p2.addTerm(1, 1);
p2.addTerm(2, 3);
p2.addTerm(2, 2);
p2.addTerm(1, 5);
System.out.println("p1 = " + p1.toString());
System.out.println("p2 = " + p2.toString());
System.out.println("Adding p1 to p2...");
p0 = p1.addPolynomial(p2);
System.out.println(p0.toString());
for(int i = 0;i < 100;i++) {
p1 = new Polynomial();
p2 = new Polynomial();
for(int j = 0;j < 4;j++) {
p1.addTerm((int) (10 * Math.random()) - 5,
(int) (4 * Math.random()));
p2.addTerm((int) (10 * Math.random()) - 5,
(int) (4 * Math.random()));
}
p0 = p1.addPolynomial(p2);
System.out.println(p1 + "\n" + p2 + "\n" + p0 + "\n");
}
}
enum Comp {
LT, EQ, GT
}
static Comp cmp(int a, int b) {
return (a < b) ? Comp.LT : (a == b) ? Comp.EQ : Comp.GT;
}
private Term poly;
public Polynomial() {
poly = null;
}
public void addTerm(int coef, int exp) {
if (coef == 0) return;
Term term = new Term(coef, exp,null);
if (poly == null) {
poly = term;
} else {
poly = poly.add(term);
}
}
#Override
public String toString() {
if (poly == null) return "0";
StringBuilder buf = new StringBuilder();
poly.writeTo(buf);
return buf.toString();
}
public Polynomial addPolynomial(Polynomial that) {
Polynomial ret = new Polynomial();
if (poly != null) {
ret.poly = new Term(poly);
if (that.poly != null) {
ret.poly = ret.poly.add(new Term(that.poly));
}
} else if (that.poly != null) {
ret.poly = new Term(that.poly);
}
return ret;
}
private class Term {
final int coef;
final int exp;
final Term next;
Term(int coef, int exp, Term next) {
this.coef = coef;
this.exp = exp;
this.next = next;
}
Term(Term copy) {
this.coef = copy.coef;
this.exp = copy.exp;
if (copy.next == null) {
this.next = null;
} else {
this.next = new Term(copy.next);
}
}
Term add(Term other) {
if (other == null) return this;
switch (cmp(this.exp, other.exp)) {
case LT: {
Term n = other.add(this);
return n;
}
case GT: {
if (next == null) {
return new Term(coef,exp,other);
}
return new Term(coef,exp,next.add(other));
}
default: {
Term n = (next==null) ? other.next : next.add(other.next);
int nc = coef+other.coef;
return (nc!=0) ? new Term(nc,exp,n) : n;
}
}
}
public void writeTo(StringBuilder app) {
if (coef != 1 || exp == 0) app.append(coef);
if (exp == 1) {
app.append("x");
} else if (exp != 0) {
app.append("x^").append(exp);
}
if (next != null) {
app.append('+');
next.writeTo(app);
}
}
}
}
Well that's certainly a bit more complex than necessary.
So you want to add a Polynomial to an already existing one, i.e.:
4*x^2 + 4 to 5*x^4+x+5, which results in: 5*x^4+4*x^2+x+9
You could obviously simplify the problem quite a bit by just using an array, but it's also not that hard with a linked list, the code should look something like this:
You have two pointers one pointing to the current position in the polynomial we want to add values (term1) and another one in the one we want to add (term2), both initialized to the lowest entry in the linked list (which we assume is sorted according to the exponent).
while term1 != NULL && term2 != NULL do:
term1 > term2:
add term2 to list
term2 = term2.next()
term2 > term1:
term1 = term1.next()
term1 = term2:
add term2 to term1
term1 = term1.next()
term2 = term2.next()
while term1 == NULL && term2 != NULL:
add term2
term2 = term2.next()
You can easily adapt that to also create a new polynomial instead of adding one to the other.
Okay so a little bit more details on how to turn the iterative solution into a recursive one:
The first thing you always have to do when thinking about recursion is your exit condition.
In this case if you think about that's easy: We only do work as long as term2 is not NULL, as soon as term2 is NULL we're finished.
The next step is thinking about a good method signature and that's also quite easy this time, since we only need the two terms, so you can just use the two iterators:
void addTogether(Iterator term1, Iterator term2); (assuming you're using an interface that's similar to the ListIterator, since you need to insert at the position before term1 - there are several ways to implement that)
ANd now you've just got to get rid of the while loops and replace them with a recursive call (in which you distinguish the different cases, do the necessary action and call it again)
We've been asked to implement a Linked Set in java. Below is my attempt, it has all the methods we are asked to write, but the method remove calls a null pointer exception without fail. Try as I might I can't seem to figure it out, any help much appreciated.
import java.util.*;
class LinkedSet<T> {
private static class Node<T> {
private T item;
private Node<T> next;
Node(T item, Node<T> next) {
this.item = item;
this.next = next;
}
}
private Node<T> head = null;
private int numItems = 0;
int size() {
return (numItems);
}
public boolean add(T t) {
if(contains(t)) return false;
Node<T> newNode = new Node(t, null); //new node to be added
if(numItems==0) {
head = newNode;
numItems++;
return true;
}
Node<T> temp = head;
while(temp.next != null) temp = temp.next;
temp.next = newNode;
numItems++;
return true;
}
public boolean remove(T t) {
if(numItems == 0) return false; //check for empty set
//was tempted to use contains here but would have made it N^2 I think
Node<T> p = head; //t if present
Node<T> pPrev = null; //previous node to p
while(p!=null && !equals(t, p.item)) {
pPrev = p;
p = p.next;
}
//t is present if node p!= null , node p != null ==> t in node p
if(p==null) return false;
else {
pPrev.next = p.next; //null pointer
numItems--;
return true;
}
}
public boolean contains(T t) {
Node<T> temp = head;
for(int i = 0; i < numItems; i++) {
if(equals(temp.item, t)) return true;
temp = temp.next;
}
return false;
}
private boolean equals(T t1, T t2) { //t1, t2 may be null
if(t1!=null) return t1.equals(t2); //learn this
else return t2 == null; //learn this
}
public static void main(String[] args) {
LinkedSet<Integer> test = new LinkedSet<Integer>();
test.add(1);
test.add(2);
test.add(3);
for(int i = 0; i < 10; i ++) {
System.out.println("Testing i = " + i + " - " + test.contains(i));
}
System.out.println(); System.out.println(); System.out.println();
System.out.println(test.remove(1));
}
}
The obvious point is that the first element in the list does not have a previous element. (Some linked list implementations will add a dummy link to handle this more cleanly.)
Look at this portion of the code:
Node<T> p = head; //t if present
Node<T> pPrev = null; //previous node to p
while(p!=null && !equals(t, p.item)) {
pPrev = p;
p = p.next;
}
If equals(t, head.item), then pPrev == null when you leave the while loop and you'll get a null pointer exception later.