Reputation: 105
For my assignment I need to create a Polynomial Class using an ArrayList that consists of Term's (a class that we created earlier in the class, ex: 7x^5). I need to make it so that when the terms are inserted into the ArrayList they are sorted in descending order.
Here is my code:
public void insert(Term aTerm)
{
Term tempTerm = new Term(0,0); //term of 0x^0 that is used to set the term to 0 after its added.
if(aTerm == null)
throw new IllegalArgumentException("The inserted term cannot be null.");
else if(aTerm.isZero() == true)
aTerm.degree(); //PLACEHOLDER not sure what to do here in order to not insert aTerm
else if(aTerm.degree() > theAL.get(0).degree())
theAL.add(0, aTerm); //adds to position 0 if largest degree
else if(aTerm.degree() < theAL.get(theAL.size() - 1).degree())
theAL.add(theAL.size() - 1, aTerm); //adds to the last position if it is the smallest degree
else
for(int i = 0; i < theAL.size(); i++)
{
if(aTerm.isZero() == true)
i = theAL.size(); //ends the for loops whenever aTerm is added and set = to 0
else if(aTerm.degree() < theAL.get(i).degree() && aTerm.degree() > theAL.get(i + 1).degree())
{
theAL.add(i + 1, aTerm); //adds between 2 terms if less than 1st term and greater than 2nd term.
aTerm.multiplyBy(tempTerm); //makes the term = zero so that the for loop can end after being added.
}
else if(aTerm.degree() == theAL.get(i).degree())
{
aTerm.addIn(theAL.get(i)); //adds into the term if the degrees are equal
aTerm.multiplyBy(tempTerm);//makes the term = zero so that the for loop can end after being added.
}
}
}
If the term is 0 I don't want it added into the Polynomial, but as you can see in my code I'm not really sure what I should do there in order to NOT insert it, so I just put a placeholder there. Any ideas what I should do there?
When I put my code through my Instructors tester it just throws a bunch of OutOfBoundsException's whenever it try's to add terms.
I understand what an OutOfBoundsException is but I'm not sure whats causing it to go out of bounds in every single scenario. I know my code probably needs a lot of work but if anyone could give me some advice I would really appreciate it. I struggled a lot trying to figure out a way to put this together, especially when I got to the part where I use the for loop to traverse through the polynomial.
Thanks for any help.
Edit:
Term Class:
public class Term implements TermInterface
//-------data
private int coefficient;
private int power;
//------constructors
//default constructor
public Term()
{
this.coefficient = 2;
this.power = 3;
}
//parameterized constructor
public Term(int aCoefficient, int aPower)
{
this.coefficient = aCoefficient;
this.power = aPower;
}
//copy constructor
public Term(Term aTerm)
{
if(aTerm != null)
{
this.coefficient = aTerm.coefficient;
this.power = aTerm.power;
}
else
throw new IllegalArgumentException("Term cannot be null");
}
//------methods
// toString() - returns its representation as a String 3x^2 for example,
public String toString()
{
if(this.coefficient == 0)
return "0";
else if(this.power == 0)
return(this.coefficient + "");
else if(this.coefficient == 1 && this.power == 1)
return "x";
else if(this.coefficient == -1 && this.power == 1)
return "-x";
else if(this.power == 1)
return(this.coefficient + "x");
else if(this.coefficient == 1)
return("x^" + this.power);
else if(this.coefficient == -1)
return("-x^" + this.power);
else
return(this.coefficient + "x^" + this.power);
}
//degree - if coefficient is 0, then (it is a constant so) returns 0.
// else returns the power
public int degree()
{
if(this.coefficient == 0)
{
return 0;
}
else
return power;
}
//evaluate - evaluates with whatever double is received
public double evaluate(double value)
{
return Math.pow(value, power) * this.coefficient;
}
//derivative - return a new Term that is the derivative. The derivative
// is calculated by:
// the coefficient of the derivative is the original coefficient times the power
// the power of the derivative is the original power minus 1
public Term derivative()
{
Term derivative = new Term(this.coefficient * this.power, this.power - 1);
return derivative;
}
//addIn: add another Term to itself.
//The Term that is received is not changed.
// if the Term that is received is null, throw a new IllegalArgumentException(<your descriptive String here>)
// if the powers are not the same, throw a new IllegalArgumentException(<your descriptive String here>)
public void addIn(Term anotherTerm)
{
if(anotherTerm == null)
throw new IllegalArgumentException("Term cannot be null");
else if(this.power != anotherTerm.power)
throw new IllegalArgumentException("Powers must be equial");
else
this.coefficient += anotherTerm.coefficient;
}
//multiplyBy: multiply itself by anotherTerm - result is a new Term that is created and returned.
//The original Term and the Term that is received are not changed.
// if the Term that is received is null, throw a new IllegalArgumentException(<your descriptive String here>)
public Term multiplyBy(Term anotherTerm)
{
if(anotherTerm != null)
throw new IllegalArgumentException("Term cannot be null");
else
{
Term multiplied = new Term(this.coefficient * anotherTerm.coefficient, this.power + anotherTerm.power);
return multiplied;
}
}
public boolean isZero()
{
if(this.coefficient == 0)
return true;
else
return false;
}
//equals: returns true if it is the same as what is received.
// If both coefficients are 0, they are automatically equal
// otherwise, both coefficients AND both exponents must be the same
public boolean equals(Object obj)
{
if (obj == null)
return false;
if (this.getClass() != obj.getClass())
return false;
Term objTerm = (Term)obj;
return(this.power == objTerm.power && this.coefficient == objTerm.coefficient);
}
}
Edit 2: Final working code:
public void insert(Term aTerm)
{
if(aTerm == null)
throw new IllegalArgumentException("The inserted term cannot be null.");
else if(aTerm.isZero() == true)
return;
int insertIndex = -1;
int i = 0;
boolean degreeEqual = false;
while(insertIndex == -1 && i < theAL.size())
{
Term tempTerm = theAL.get(i);
if(tempTerm.degree() == aTerm.degree())
{
degreeEqual = true;
aTerm.addIn(tempTerm);
insertIndex = i;
}
else if(aTerm.degree() > tempTerm.degree())
insertIndex = i;//ends the loop because we know where to put insert the term
i++; //increment index counter
}
if(degreeEqual == false)
{
if(insertIndex >= 0) //check to make sure index location is valid.
theAL.add(insertIndex, aTerm);
else
theAL.add(aTerm);//insert term at the end because it is less than other terms
}
else
{
if(insertIndex >= 0) //check to make sure index location is valid.
{
theAL.remove(insertIndex);
theAL.add(insertIndex, aTerm);
if(theAL.get(insertIndex).isZero())
{
theAL.remove(insertIndex);
}
}
else
theAL.add(aTerm);//insert term at the end because it is less than other terms
}
}
Upvotes: 1
Views: 1538
Reputation: 339
I can see where you're going with this, but you've made your testing and looping far more complex than need be. I could be misinterpreting the intent of the algorithm, but I would simplify down to something like this:
if(aTerm == null || aTerm.isZero()) {
return;// this is not a valid term
}
int insertIndex = -1;
int i = 0;
boolean addToList = true;
// loop until you've found your place, make sure to test for end conditions
// so you don't hit an IndexOutOfBounds error or create an infinite loop
while(insertIndex == -1 && i < theAL.size() && addToList) {
Term thisTerm = theAL.get(i);
if(aTerm.degree() == thisTerm.degree()) {
thisTerm.addIn(aTerm);
addToList = false;
} else if(aTerm.degree() > thisTerm.degree()) {
insertIndex = i;// this will end the loop, we know where to sort
// this element in our array
}
i++;// increment our counter
}
if(addToList) {
// make sure we found a valid location, if so, add in our term
if(insertIndex >= 0) {
theAL.add(insertIndex, aTerm);
} else {
theAL.add(aTerm); // insert the term at the end, it's less than all
// other terms in the list, or the list is empty
}
}
Upvotes: 1
Reputation: 1957
Most likely this line causes some problems:
else if(aTerm.degree() < theAL.get(i).degree() && aTerm.degree() > theAL.get(i + 1).degree())
You try to access the i + 1
element of your list. Because of your iterations walks over:
for(int i = 0; i < theAL.size(); i++)
this will cause a memory access "one greater the list size" and therefore an OutOfBoundException. Just my guess till you can share your Term class. It could also be a problem when the list is empty (before the first element is inserted) because you access the 0
element of the list which does not exist.
For your other question according to the null Term:
else if(aTerm.isZero() == true)
aTerm.degree();
you could just return
:
else if(aTerm.isZero() == true)
return;
and do nothing if there is nothing to do.
Upvotes: 0