Reputation: 11
I have the below code, all seems to work fine, except for the sub()
function when attempting to subtract one polynomial from another
p4 = p1.sub(p2);
I see the output: x+3x^5-5x^8
, when I expect to see: x-2x^3+7x^5-2x^7-5x^8
. I cannot figure out what is wrong with my code, any help is greatly appreciated. Thanks in advance.
public class Polynomial {
public static final int MAX_NUMBER_OF_COEFFICIENTS = 30;
private int[] coefficients = new int[MAX_NUMBER_OF_COEFFICIENTS];
public Polynomial() {
}
public Polynomial(int coefficient, int exponent) {
coefficients[exponent] += coefficient;
}
public Polynomial(int[] newcoefficients) {
for (int i = 0 ; i < MAX_NUMBER_OF_COEFFICIENTS; i++) {
coefficients[i] += newcoefficients[i];
}
}
public void insert(int coefficient, int exponent) {
coefficients[exponent] += coefficient;
}
public Polynomial add(Polynomial otherPolynomial) {
for (int i = 0 ; i < MAX_NUMBER_OF_COEFFICIENTS; i++) {
if (otherPolynomial.coefficients[i] != 0)
this.coefficients[i] += otherPolynomial.coefficients[i];
}
return new Polynomial(this.coefficients);
}
public Polynomial sub(Polynomial otherPolynomial) {
for (int i = 0 ; i < MAX_NUMBER_OF_COEFFICIENTS; i++) {
if (otherPolynomial.coefficients[i] != 0)
this.coefficients[i] -= otherPolynomial.coefficients[i];
}
return new Polynomial(this.coefficients);
}
public void sub(int coefficient, int exponent) {
this.coefficients[exponent] -= coefficient;
}
public void remove(int exponent) {
coefficients[exponent] = 0;
}
public void printout() {
boolean firstPrint = false;
if (coefficients[0] != 0) {
System.out.print(coefficients[0]);
firstPrint = true;
}
for (int i = 1 ; i < MAX_NUMBER_OF_COEFFICIENTS; i ++) {
if (coefficients[i] != 0) {
if (firstPrint == false) {
System.out.print(coefficients[i] + "x^" + i);
firstPrint = true;
}
else {
System.out.print(" + " + coefficients[i] + "x^" + i);
}
}
}
System.out.println();
}
public static void main(String[] args) {
Polynomial p1 = new Polynomial(1,1);
Polynomial p2 = new Polynomial(2,3);
Polynomial p3 = new Polynomial();
Polynomial p4 = new Polynomial();
Polynomial p5 = new Polynomial(6,3);
try {
p1.insert(3,5);
p1.sub(5,8);
p1.printout();
p2.sub(4,5);
p2.add(new Polynomial(2,7));
p2.printout();
p3 = p1.add(p2);
p3.printout();
p4 = p1.sub(p2);
p4.printout();
p5.insert(2,5);
p5.remove(3);
p5.printout();
//p1.add(new Polynomial(2,-1));
}
catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Exponent cannot be negative. " + e);
}
}
}
Upvotes: 0
Views: 5528
Reputation: 1825
The function is working as expected. What you are not aware of (maybe you are) is that when you call p3 = p1.add(p2);
you will change p1
and then return a new polynomial with p1
's coefficients. So when you call p4 = p1.sub(p2)
you will have the same p1
that was before the p3 = p1.add(p2)
.
So what you were having was more like this:
p3 = p1* = p1 + p2
p4 = p1** = p1* - p2
Where p1*
is the result of p1 + p2
. So what you have now was:
p4 = p1* - p2 = (p1 + p2) - p2 = p1
Again, if you want to return new polynomial, DONT CHANGE THE EXISTING ONE.
Change both functions add(Polynomial ..)
and sub(Polynomial ..)
:
public Polynomial add(Polynomial otherPolynomial) {
int coeff[] = new int[MAX_NUMBER_OF_COEFFICIENTS];
System.arraycopy(this.coefficients, 0, coeff, 0, MAX_NUMBER_OF_COEFFICIENTS);
for (int i = 0 ; i < MAX_NUMBER_OF_COEFFICIENTS; i++) {
// why is this anyway?
//if (otherPolynomial.coefficients[i] != 0)
coeff[i] += otherPolynomial.coefficients[i];
}
return new Polynomial(coeff);
}
public Polynomial sub(Polynomial otherPolynomial) {
int coeff[] = new int[MAX_NUMBER_OF_COEFFICIENTS];
System.arraycopy(this.coefficients, 0, coeff, 0, MAX_NUMBER_OF_COEFFICIENTS);
for (int i = 0 ; i < MAX_NUMBER_OF_COEFFICIENTS; i++) {
// why is this anyway?
//if (otherPolynomial.coefficients[i] != 0)
coeff[i] -= otherPolynomial.coefficients[i];
}
return new Polynomial(coeff);
}
This way, you wont change p1
when you are assigning (or calling copy constructor on) p3
and p4
.
EDIT:
Based on your code, it is IMPOSSIBLE to have one function that once adds to the original caller and once doesn't change it, which is what your program wants. When you call p2.add(new Polynomial(2,7));
you want to change p2
and in the same time you want p1.add(p2)
not to change p1
which is impossible to achieve in one function.
If you want to have the output you suggested in your question, change
p2.add(new Polynomial(2,7));
to
p2 = p2.add(new Polynomial(2,7));
EDIT2: If I wanted to do it, I would really do it a whole different way. I would have all add/sub
functions with void
return types, and have two static add/sub
functions that return new Polynomial
and accept two Polynomials
. These static
methods cannot be called on an instance (like p1
) but can only be called on the class.
Therefore, this would be my code if I was designing it:
public static Polynomial add(Polynomial p1, Polynomial p2){
Polynomial newPolynomial = new Polynomial();
for(int i=0;i< MAX_NUMBER_OF_COEFFICIENTS;i++)
newPolynomial.coefficients[i] = p1.coefficients[i]+p2.coefficients[i];
return newPolynomial;
}
public static Polynomial sub(Polynomial p1, Polynomial p2){
Polynomial newPolynomial = new Polynomial();
for(int i=0;i< MAX_NUMBER_OF_COEFFICIENTS;i++)
newPolynomial.coefficients[i] = p1.coefficients[i]-p2.coefficients[i];
return newPolynomial;
}
public void add(Polynomial otherPolynomial) {
for (int i = 0 ; i < MAX_NUMBER_OF_COEFFICIENTS; i++) {
coefficients[i] += otherPolynomial.coefficients[i];
}
}
public void sub(Polynomial otherPolynomial) {
for (int i = 0 ; i < MAX_NUMBER_OF_COEFFICIENTS; i++) {
coefficients[i] -= otherPolynomial.coefficients[i];
}
}
When you have it this way, you CANNOT say p3.add(p1, p2)
. This will change your main code to:
p1.insert(3,5);
p1.sub(5,8);
p1.printout();
p2.sub(4,5);
p2.add(new Polynomial(2,7));
p2.printout();
p3 = Polynomial.add(p1, p2);
p3.printout();
p4 = Polynomial.sub(p1, p2);
p4.printout();
p5.insert(2,5);
p5.remove(3);
p5.printout();
As you can see for p3
and p4
you will be calling Polynomial.add
and Polynomial.sub
. You can best understand this by understanding Math.*
methods. All Math
library is static
so you cannot create an instance of it, but you can say Math.abs
... Here it is the same concept, you can call Polynomial.add
and so on
Upvotes: 2
Reputation: 16932
In your code you are mixing two concepts.
1) (Immutable Ojects) Either you should code your Polynomial as immutable, that is add and sub do not alter the member field but create a new array and return a new object - in this case you have to write
Polynomial p3 = p1.add(p2)
and p1 remains unchanged -, or
2) (Mutable Objects) you should code your Polynomial as mutable and return just this (and NOT create an return a new object) - in this case you can write
p1.add(p2)
which similar to p1 = p1.add(p2) in the case 1.
In case 2) you can do
p1.add(p2).sub(p3)
which is similar to p1 = p1.add(p2).sub(p3) in case 1).
What you are observing is called a side effect, since your operation is modifying the object. Avoiding side effects is maybe one of the main motivation of writing code that leaves object immutable.
Try
public Polynomial add(Polynomial otherPolynomial) {
Polynomial result = new Polynomial();
for (int i = 0 ; i < MAX_NUMBER_OF_COEFFICIENTS; i++) {
if (otherPolynomial.coefficients[i] != 0)
result.coefficients[i] = this.coefficients[i] + otherPolynomial.coefficients[i];
}
return result;
}
and similar for sub.
Search the keywords immutable, mutable and side effect for more details.
Upvotes: 1
Reputation: 1258
Looks fine to me you start with line
Polynomial p1 = new Polynomial(1,1);
Which is basically 1*x then you call the following line
p1.insert(3,5);
Which sets index 5 of your array to be 3 so now you have 1*x+3x^5 and last you call
p1.sub(5,8);
Which subtracts 5 from the value in the 8 index of your array so now you have 1x^1 + 3x^5 + -5x^8
Upvotes: 0