Hi, I'm a first year computer science student having a problem with part of an assignment. The goal of the assignment was to store the coefficients for a polynomial and find its roots using both an array and a linked list. I was able to successfully complete the array version; however the linked list is giving me a headache.
I am able to successfully store the initial round of variables provided in polynomial.java; however, things go a bit crazy once the root calculations begin and the program ends up terminating without giving any roots. I have a feeling this might be being cause by the way the Polynomial.java calculates the roots causing problems with the linked list; however, I am not allowed to change polynomial.java, only LinkedIntList.java. I have been banging my head against the computer for the past 7 hours trying to find the bug and am about ready to just give up on the assignment as I can't reach the professor for help.
I'd greatly appreciate anyone who can spot the bug or are willing to look over the code to provide tips on what I may be doing wrong or how I can work around my problem.
File 1: Node.Java
package lists;
public class Node
{
int element;
Node next = null;
/**
* Constructor which creates a new node containing the value specified by item
*
*/
public Node (int item)
{
element = item;
}
/**
* Returns the current value of the data item contained inside this node
*/
public int getElement ()
{
return element;
}
/**
* Sets the current value of the data item contained inside this node to
* the value specified by newVal
*/
public void setElement (int newVal)
{
element = newVal;
}
/**
* Links this node to the node passed in as an argument
*/
public void setNext (Node n)
{
next = n;
}
/**
* Returns a reference to the node that follows this node in the
* linked list, or null if there is no such node
*/
public Node getNext ()
{
return next;
}
/**
* Returns a string based representation of the data item contained
* in this node.
*/
public String toString()
{
return Integer.toString(element);
}
}
File 2: LinkedIntList.Java
package lists;
public class LinkedIntList implements IntList
{
Node head = null;
int count = 0;
/**
* Standard Java toString method that returns a string
* equivalent of the IntList
*
* @return a string indicating the values contained in
* this IntList (ex: "[5 3 2 9 ]")
*/
public String toString()
{
String retVal = "";
String intermediary = "";
Node n;
for (n = head; n.getNext() != null; n = n.getNext())
{
intermediary = Integer.toString(n.getElement());
retVal = intermediary + " " + retVal;
}
retVal = n.getElement() + " " + retVal;
return retVal;
}
/**
* Adds the given value to the <b>end</b> of the list.
*
* @param value the value to add to the list
*/
public void add (int value)
{
Node newNode = new Node (value);
if (head == null)
head = newNode;
else
{
Node n = head;
while (n.getNext() != null)
{
n = n.getNext();
}
n.setNext(newNode);
}
count++;
}
/**
* Returns the number of elements currently in the list.
*
* @return the number of items currently in the list
*/
public int size()
{
return count;
}
/**
* Returns the element at the specified position in this list.
*
* @param index index of the element to return (zero-based)
* @return the element at the specified position in this list.
* @throws IndexOutOfBoundsException if the index is out of range
* (index < 0 || index >= size()).
*/
public int get(int index) throws IndexOutOfBoundsException
{
Node reference = head;
if (index < 0 || index >= count)
{
throw new IndexOutOfBoundsException("Index out of bounds.");
}
for (int i = 0; i != index; i++)
{
reference.getNext();
}
return reference.getElement();
}
/**
* Replaces the element at the specified position in this list with
* the specified element.
*
* @param index index of the element to return (zero-based)
* @param value element to be stored at the specified position.
* @throws IndexOutOfBoundsException if the index is out of range
* (index < 0 || index >= size()).
*/
public void set (int index, int value) throws IndexOutOfBoundsException
{
if (index < 0 || index >= count)
{
throw new IndexOutOfBoundsException("Index out of bounds.");
}
Node newNode = new Node (value);
Node trailingReference = head;
Node leadingReference = head.getNext();
for(int i = 1; i != index; i++)
{
trailingReference = leadingReference;
leadingReference = leadingReference.getNext();
}
trailingReference.setNext(newNode);
newNode.setNext(leadingReference);
count++;
}
}
File 3: IntList.Java
package lists;
public interface IntList
{
/**
* Standard Java toString method that returns a string
* equivalent of the IntList
*
* @return a string indicating the values contained in
* this IntList (ex: "[5 3 2 9 ]")
*/
public String toString();
/**
* Adds the given value to the <b>end</b> of the list.
*
* @param value the value to add to the list
*/
public void add (int value);
/**
* Returns the number of elements currently in the list.
*
* @return the number of items currently in the list
*/
public int size();
/**
* Returns the element at the specified position in this list.
*
* @param index index of the element to return (zero-based)
* @return the element at the specified position in this list.
* @throws IndexOutOfBoundsException if the index is out of range
* (index < 0 || index >= size()).
*/
public int get(int index);
/**
* Replaces the element at the specified position in this list with
* the specified element.
*
* @param index index of the element to return (zero-based)
* @param value element to be stored at the specified position.
* @throws IndexOutOfBoundsException if the index is out of range
* (index < 0 || index >= size()).
*/
public void set (int index, int value);
}
File 4: Polynomial.java
/**
* A program which finds the integer (whole number) roots of a
* polynomial with integer coeffecients. The method used is based
* upon the ideas presented at:
*
*/
import lists.*;
public class Polynomial
{
public static void main (String [] args)
{
// trick to get out of static context
new Polynomial().runMe();
}
public void runMe()
{
IntList poly = new LinkedIntList();
// Create the polynomial:
// 3x^10 + 12x^9 - 496x^8 - 211x^7 + 18343x^6 -43760x^5 +
// 11766x^4 + 26841x^3 - 126816x^2 + 37278x - 84240
poly.add (-84240);
poly.add (37278);
poly.add (-126816);
poly.add (26841);
poly.add (11766);
poly.add (-43760);
poly.add (18343);
poly.add (-211);
poly.add (-496);
poly.add (12);
poly.add (3);
System.out.print ("Finding the integer roots of the polynomial: ");
System.out.println (poly);
IntList roots = findRoots (poly);
for (int x = 0; x < roots.size(); x++)
System.out.println ("Root found: " + roots.get(x));
}
/**
* Find all *integer* roots of the polynomial represented by the IntList.
*
* @param poly a polynomial encoded as a list of coefficients
* @return a list of all roots of the given polynomial. Note that
* the returned list may have duplicate entries.
*/
public IntList findRoots (IntList poly)
{
IntList l = new LinkedIntList();
int q = poly.get(poly.size() - 1);
int p = poly.get(0);
IntList pVals = divTerms(Math.abs(p));
IntList qVals = divTerms(Math.abs(q));
IntList possibleZeros = findPotentialZeros(pVals, qVals);
//for (Integer i : possibleZeros)
for (int x = 0; x < possibleZeros.size(); x++)
if (eval (poly, possibleZeros.get(x)) == 0)
l.add (possibleZeros.get(x));
return l;
}
/**
* Evaluates the polynomial represented by the IntList with the given
* value.
*
* @param poly a
* @param val the value to evaluate the polynomial with.
* @return f(val), where f is the polynomial encoded as poly
*/
private int eval (IntList poly, int val)
{
int result = 0;
for (int x = poly.size() - 1; x >= 0; x--)
result += poly.get(x) * (int) Math.pow (val, x);
return result;
}
private IntList findPotentialZeros (IntList plist, IntList qlist)
{
IntList result = new LinkedIntList();
for (int p = 0; p < plist.size(); p++)
{
for (int q = 0; q < qlist.size(); q++)
{
// add it only if q evenly divides p (we're looking
// for integer roots only
if (plist.get(p) % qlist.get(q) == 0)
{
int x = plist.get(p) / qlist.get(q);
result.add (x);
result.add (-x);
}
}
}
return result;
}
/**
* Find all integers that evenly divide i.
*
* @param i the integer to find all divisors of
* @return a list of all integers that evenly divide i
*/
private IntList divTerms (int i)
{
IntList v = new LinkedIntList();
// 1 divides all numbers
v.add(1);
// find all divisors < i and >= 2
for (int x = 2; x < i; x++)
if (i % x == 0)
v.add(x);
// all numbers are evenly divisible by themselves
if (i > 1)
v.add(i);
return v;
}
}