Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 4 years ago.
Improve this question
So I'm trying to add 2 polynomials together, and I have created object type Polynomial of ArrayBasedPoly, and that object is an array of the coeff, and the degree is starting from 0.
Ex: [1, 0, 3, 4] is 4x^3 + 3x^2 + 1
In my add class, I'm trying to add the 2 arrays together ->
Ex: p1 = [1, 0, 3, 4], p2 = [-2, -5], Sum[] = [-1, -5, 3, 4]
However, in the add method, it won't recognize p2 as an array, even though the object is an array.
EDIT: Now I know that I need a method to find the length of the array of object p, however, even when I have a separate method, it still can't find it?
public class ArrayBasedPoly extends Polynomial
{
private double [] poly;
public ArrayBasedPoly(double [] poly)
{
this.poly = poly;
}
public ArrayBasedPoly(double coeff, int expon)
{
super.coeff = coeff;
super.expon = expon;
}
public ArrayBasedPoly add(ArrayBasedPoly p)
{
double [] temp = new double [Math.max(p.length, poly.length)]; //<=== Here
return null; //temp
}
public String toString()
{
String s = "";
if (poly == null)
{
return super.toString(); // no poly array
}
for(int i = poly.length - 1; i >= 0; i--)
{
if (i != poly.length - 1 && poly[i] > 0) //adds + sign
{
s += " + ";
}
if (poly[i] != 0) // ignores the 0 in the array
{
if (i == 1) //if expon is 1, doesn't do the ^1
{
s += poly[i] + "x";
} else if (i > 0) { // normal
s += poly[i] + "x^" + i;
} else {
s += poly[i]; // if expon = 0, just prints out the coeff
}
}
}
return s;
}
public static void main (String [] args)
{
double [] c = {1, 0, 3, 4};
double [] c1 = {-2, -5};
Polynomial p1 = new ArrayBasedPoly (c);
System.out.println("p1(x) = " + p1);
Polynomial p2 = new ArrayBasedPoly (c1);
System.out.println("p2(x) = " + p2);
Polynomial p3 = new ArrayBasedPoly(-4, 1);
System.out.println("p3(x) = " + p3);
Polynomial p = p1.add(p2);//.add(p2);
System.out.println("p(x) = " + p);
Polynomial p4 = p.subtract(p3);
System.out.println("p4(x) = " + p4);
Polynomial p5 = p4.getDerivative();
System.out.println("p5(x) = " + p5);
System.out.println("p5(0) = " + p5.evaluate(0));
System.out.println("p5(1) = " + p5.evaluate(1));
}
} //ArrayBasedPoly
public class Polynomial
{
protected double coeff;
protected int expon;
public Polynomial()
{
coeff = 1;
expon = 1;
}
public Polynomial(double coeff, int expon)
{
this.coeff = coeff;
this.expon = expon;
}
public Polynomial(Polynomial p)
{
this.coeff = p.coeff;
this.expon = p.expon;
}
public int getDegree()
{
return expon;
}
public double getCoeff()
{
return coeff;
}
public double evaluate(double x)
{
return Math.pow(x, expon) * coeff;
}
public Polynomial add (Polynomial p)
{
Polynomial temp = new Polynomial();
if (expon != p.expon)
{
return null;
}
temp.coeff = coeff + p.coeff;
temp.expon = expon;
return temp;
} //add
public Polynomial subtract (Polynomial p)
{
Polynomial temp = new Polynomial();
if (expon != p.expon)
{
return null;
}
temp.coeff = coeff - p.coeff;
temp.expon = expon;
return temp;
} //subtract
public Polynomial getDerivative()
{
Polynomial temp = new Polynomial(coeff, expon);
if (expon == 1)
{
temp.coeff = coeff;
temp.expon = 0;
return temp;
}
temp.coeff *= temp.expon;
temp.expon--;
return temp;
} //derivative
public String toString()
{
if (expon == 0)
{
return coeff + "";
}
if (expon == 1)
{
return coeff + "x";
}
return coeff + "x^" + expon;
} //toString
public static void main (String [] args)
{
//Coefficient, Exponent
Polynomial p1 = new Polynomial(3, 2); //3x^2
System.out.println("P1: " + p1);
System.out.println();
System.out.println("Derivative of P1: " + p1.getDerivative());
System.out.println();
System.out.println("P1 if x=2: " + p1.evaluate(2));
Polynomial p2 = new Polynomial(2, 2);
System.out.println();
System.out.println("P2: " + p2);
System.out.println();
System.out.println("P1+P2: " + p1.add(p2));
System.out.println();
System.out.println("P1-P2: " + p1.subtract(p2));
Polynomial p3 = new Polynomial(2, 1);
System.out.println();
System.out.println("P3: " + p3);
System.out.println();
System.out.println("Derivative of P3: " + p3.getDerivative());
System.out.println();
System.out.println("P1+P3: " + p1.add(p3));
} //Main
} //Polynomial
/*
----jGRASP exec: java Polynomial
P1: 3.0x^2
Derivative of P1: 6.0x^1
P1 if x=2: 12.0
P2: 2.0x^2
P1+P2: 5.0x^2
P1-P2: 1.0x^2
P3: 2.0x^1
Derivative of P3: 1.0x^0
P1+P3: null
----jGRASP: operation complete.
*/
It seems like I have made an error, and that the "add" method should
have the parameter "Polynomial" instead because in the main method the
object are of type Polynomial. However, when I use the Polynomial
parameter and have a getLength() method, it still can't find it. –
Agramon
The problem is in the method call:
Polynomial p = p1.add(p2);//.add(p2);
because p1 is a Polynomial it will check THAT class for the add method. You need to cast p1. And then you would need to cast p2 since the method is expecting an ArrayBasedPoly.
Polynomial p = ((ArrayBasedPoly) p1).add((ArrayBasedPoly) p2);
You have multiple issues in this piece of code.
First, ArrayBasedPoly should not be extending Polynomial, as it is not a subclass of it, but an array representation of it. To solve this issue, you should keep an array/list of Polynomial inside ArrayBasedPoly like this:
public class ArrayBasedPoly {
Polynomial[] polyArray;
// or alternatively: List<Polynomial> polyArray;
// or even better, use a sorted structure such as skiplist
}
Second, as Pereira pointed out, you are mixing up these two classes.
The Polynomial class does not contain add().
You can only add two ArrayBasePoly.
Related
This question already has answers here:
Class is not abstract and does not override abstract method
(2 answers)
Closed 3 years ago.
I've been working on a program that can find the root of a polynomial for school, and do various other polynomial related stuff like adding them together or finding the value of a polynomial with a given x. While the other two classes I made work fine (they find the root of a sin and cos function), my FuncPoly class seems to be conflicting with my evaluate method somehow, and doesn't want to inherit it. This is my exact error message:
.\FuncPoly.java:1: error: FuncPoly is not abstract and does not override abstract method evaluate(double) in Function
public class FuncPoly extends Function{
I've tried fiddling with the evaluate method a little bit and trying to add some overrides in, but it hasn't been helping me very much. I need help finding what is causing this error; maybe its related to my constructor?. Thanks for reading and your help! Code is below; there is a lot in there, but I don't think most of it is pertinent to the question.
public abstract double evaluate(double x); //Basically just a filler for SinFunc and CosFunc
public double findRoot(double a, double b, double epsilon){
double x = ( a + b ) / 2;
if (Math.abs( a - x) <= epsilon){
return x;
}else if (evaluate(x)*evaluate(a) >= 0){
return findRoot(x, b, epsilon);
}else{
return findRoot(a, x, epsilon);
}
}
public static void main(String[] args){
//Tests SinFunc and CosFunc
SinFunc q = new SinFunc();
CosFunc w = new CosFunc();
System.out.println("The root of sin(x) with the numbers entered with the given epsilon is: " + q.findRoot(3,4,.00000001));
System.out.println("The root of cos(x) with the numbers entered with the given epsilon is: " + w.findRoot(1,3,.00000001));
//Tests the FuncPoly stuff
int[] test1 = {1,0,-3};
int[] test2 = {1,-1,-2};
FuncPoly poly1 = new FuncPoly(test1);
FuncPoly poly2 = new FuncPoly(test2);
System.out.println("The root of x^2 + (-3) is" + poly1.findRoot(0,10,.00000001));
}
}
____________________________
public class FuncPoly extends Function{
public int coefficients[];
public FuncPoly(int[] coefficients){
//Constructor
this.coefficients = coefficients;
}
public int degree(){
//Finds the highest power by finding the location of the last number in the array.
return this.coefficients.length - 1;
}
public String toString(){
//Converts a polynomial to a string
StringBuilder poly = new StringBuilder();
for(int i = degree(); i >= 0; i--){
if (i == degree()){
poly.append(this.coefficients[i] + "x^" + degree());
}else{
if (this.coefficients[i] == 0){
System.out.println(i);
}else if (i == 0){
poly.append(" + " + this.coefficients[0]);
} else if ( i == 1){
poly.append(" + " + this.coefficients[1] + "x");
} else{
poly.append(" + " + this.coefficients[i] + "x^" + i);
}
}
}
return poly.toString();
}
public FuncPoly add(FuncPoly a){
//Adds the selected polynomial and the last called polynomial together and returns the array.
if (this.degree() > a.degree()){
int[] polyAdd = new int[this.degree() + 1];
for (int i = 0; i <= a.degree(); i++){
polyAdd[i] = a.coefficients[i] + this.coefficients[i];
}
for (int i = a.degree() + 1; i < this.degree() + 1; i++){
polyAdd[i] = this.coefficients[i];
}
FuncPoly polyResult = new FuncPoly(polyAdd);
return polyResult;
} else if (this.degree() < a.degree()){
int[] polyAdd = new int[a.degree() + 1];
for (int i = 0; i <= this.degree(); i++){
polyAdd[i] = a.coefficients[i] + this.coefficients[i];
}
for (int i = this.degree() + 1; i < degree() + 1; i++){
polyAdd[i] = a.coefficients[i];
}
FuncPoly polyResult = new FuncPoly(polyAdd);
return polyResult;
} else {
int[] polyAdd = new int[a.degree() + 1];
for (int i = 0; i < a.degree() + 1; i++){
polyAdd[i] = a.coefficients[i] + this.coefficients[i];
}
FuncPoly polyResult = new FuncPoly(polyAdd);
return polyResult;
}
}
public double value(double x){
//Finds the value of polynomial with a given x.
double sum = 0;
for(int i = 0; i < this.degree() + 1; i++){
sum += this.coefficients[i] * Math.pow(x,i);
}
return sum;
}
}
As far as I can tell, your value() method in FuncPoly needs to be renamed to evaluate() to successfully implement the abstract evaluate() method from the Function class.
So I've been tasked to work on an algorithm based on Random Mutation Hill Climbing. I have a method RMHC that takes in an ArrayList of weights and two ints, one for number of weights and another for iterations. My instructions tell me to create an initial solution, copy it and then apply a mutation method SmallChange() to the initial solution. I was also instructed on how to copy the solution with the GetSol() method in my ScalesSolution class. The mutation takes in a binary String value (i.e 11101) and changes a random substring in the binary to either 0 or 1 so I may be met with an output such as 10101 if the 2nd substring is mutated.
My issue is that when I make the SmallChange() to my solution, it makes the change to the original solution also.
I've already tried adding a copy constructor as what was suggested in another question I'd found, but it did not work.
Main Method
public class Worksheet9 {
public static void main(String[] args) {
ArrayList<Double> myArray = new ArrayList<Double>();
myArray.add(1.0);
myArray.add(2.0);
myArray.add(3.0);
myArray.add(4.0);
myArray.add(10.0);
RMHC(myArray, 5, 2);
}
RMHC Method
public static ScalesSolution RMHC(ArrayList<Double> weights,int n,int iter)
{
ScalesSolution oldsol = new ScalesSolution(n);
ScalesSolution newsol = new ScalesSolution(oldsol.GetSol());
//Attempting Copy Constructor
ScalesSolution newsol = new ScalesSolution(oldsol);
double origfitness = oldsol.ScalesFitness(weights);
System.out.println("Original Fitness: " + origfitness);
double origfitness1 = newsol.ScalesFitness(weights);
System.out.println("Cloned Original Fitness: " + origfitness1);
newsol.SmallChange();
double origfitness2 = newsol.ScalesFitness(weights);
System.out.println("Changed Fitness: " + origfitness2);
double origfitness3 = oldsol.ScalesFitness(weights);
System.out.println("Cloned Original Fitness: " + origfitness3);
return(oldsol);
}
}
ScalesSolution Class
import java.util.ArrayList;
import java.util.Random;
public class ScalesSolution
{
private static String scasol;
//Creates a new scales solution based on a string parameter
//The string parameter is checked to see if it contains all zeros and ones
//Otherwise the random binary string generator is used (n = length of parameter)
#
public ScalesSolution(ScalesSolution another) {
this.scasol = another.scasol; // you can access
}
public void SmallChange() {
int n = scasol.length();
String s = scasol;
Random rand = new Random();
int p = (rand.nextInt(n));
String x;
x = scasol.substring(0, p);
if (scasol.charAt(p) == '0') {
x += '1';
} else {
x += '0';
}
x += scasol.substring(p + 1, n);
scasol = x;
}
public String GetSol()
{
return(scasol);
}
public ScalesSolution(String s)
{
boolean ok = true;
int n = s.length();
for(int i=0;i<n;++i)
{
char si = s.charAt(i);
if (si != '0' && si != '1') ok = false;
}
if (ok)
{
scasol = s;
}
else
{
scasol = RandomBinaryString(n);
}
}
private static String RandomBinaryString(int n)
{
String s = new String();
//Code goes here
//Create a random binary string of just ones and zeros of length n
for(int i = 0; i < n; i++){
int x = CS2004.UI(0, 1);
if(x == 0){
s += '0';
} else if (x == 1) {
s += '1';
}
}
return(s);
}
public ScalesSolution(int n)
{
scasol = RandomBinaryString(n);
}
//This is the fitness function for the Scales problem
//This function returns -1 if the number of weights is less than
//the size of the current solution
public static double ScalesFitness(ArrayList<Double> weights)
{
if (scasol.length() > weights.size()) return(-1);
double lhs = 0.0,rhs = 0.0;
int n = scasol.length();
for(int i = 0; i < n; i++){
if (scasol.charAt(i) == '0') {
lhs += weights.get(i);
}
else {
rhs += weights.get(i);
}
}
//Code goes here
//Check each element of scasol for a 0 (lhs) and 1 (rhs) add the weight wi
//to variables lhs and rhs as appropriate
return(Math.abs(lhs-rhs));
}
//Display the string without a new line
public void print()
{
System.out.print(scasol);
}
//Display the string with a new line
public void println()
{
print();
System.out.println();
}
}
When I call the RMHC function in the main method, I get an output like this:
Original Fitness: 16.0
Cloned Original Fitness: 16.0
Changed Fitness: 14.0
Cloned Original Fitness: 14.0
The 2nd Cloned Original Fitness should also be value 16.0 in this example. Once I figure out this initial issue, I will implement the code into a for loop to include the iterations. Thanks.
Assuming this is where you try to copy your data:
ScalesSolution oldsol = new ScalesSolution(n);
ScalesSolution newsol = new ScalesSolution(oldsol.GetSol());
This doesn't work because the variable is static:
public class ScalesSolution
{
private static String scasol;
//...
public String GetSol()
{
return(scasol);
}
Since all you do is assign the value to the static string scasol, no actual change or copy is made.
I am trying to print out the Depth First Traversal of my "graph" program.
The DepthFirstTraversal(int v) method is supposed to start from the first index, which is supposed to be A. However, it seems like it is skipping this.
Any suggestions?
I have tried changing the value v from 1 to 0, but this just prints an extra 0 on top of the same code.
import java.util.Arrays;
import java.util.Iterator;
public class Graph {
private boolean[][] edges;
private int[] labels;
private int N; //number of vertices;
//constructor. This constructor will create a matrix of size n by n.
public Graph(int n) {
N=n;
edges = new boolean[n][n];
labels = new int[n];
}
//this method will allow user to add an edge
public void addEdge(int source, int target) {
edges[source][target] = true;
}
//this method will return the label of the vertex
public int getLabel(int vertex) {
return labels[vertex];
}
//this method will allow user to remove an edge
public void removeEdge(int source, int target) {
edges[source][target] = false;
}
//this method will allow user to set a label
public void setLabels(int vertex, int newLabel) {
labels[vertex] = newLabel;
}
//this method will return the size of the labels array
public int size() {
return labels.length;
}
//this method will grab the neighbors of the desired vertex
public int[] neighbors(int vertex) {
int i;
int counter = 0;
int[] result;
for (i = 0; i < labels.length; i++) {
if (edges[vertex][i])
counter++;
}
result = new int[counter];
counter = 0;
for (i = 0; i < labels.length; i++) {
result[counter++] = i;
}
return result;
}
//this method will print out the vertices starting from the first value
I tried fixing my code a little, but I ran into another problem.
I do have to use neighbors method and also I cannot use recursion.
public void DepthFirstTraversal(int v) {
boolean[] visited = new boolean[N];
Stack<Integer> stack = new Stack<>();
stack.add(v);
visited[v]=true;
while(!stack.isEmpty()){
int i = stack.pop();
if (i == 1) {
System.out.print("A" + "-");
} else if (i == 2) {
System.out.print("B" + "-");
} else if (i == 3) {
System.out.print("C" + "-");
} else if (i == 4) {
System.out.print("D" + "-");
} else if (i == 5) {
System.out.print("E" + "-");
} else if (i == 6) {
System.out.print("F" + "-");
} else if (i == 7) {
System.out.print("G" + "-");
} else if (i == 8) {
System.out.print("H" + "-");
} else if (i == 9) {
System.out.print("I" + "-");
}
System.out.print(labels[i] + " \n");
int[] neighborsOfI = neighbors(i);
for(int k=0;k<neighborsOfI.length;k++){
int neighborTest = neighborsOfI[k];
if(!visited[neighborTest]){
stack.add(neighborTest);
visited[neighborTest]=true;
}
}
}
}
}
public class graphDemo {
public static void main(String args[]){
Graph graph = new Graph(10);
graph.addEdge(1,1);
graph.addEdge(2,3);
graph.addEdge(3,5);
graph.addEdge(4,7);
graph.addEdge(5,9);
graph.addEdge(6,2);
graph.addEdge(7,3);
graph.addEdge(8,5);
graph.addEdge(9,8);
graph.setLabels(1,9);
graph.setLabels(2,3);
graph.setLabels(3,5);
graph.setLabels(4,7);
graph.setLabels(5,4);
graph.setLabels(6,8);
graph.setLabels(7,6);
graph.setLabels(8,2);
graph.setLabels(9,1);
System.out.println("Depth First Traversal from first value: \n");
graph.DepthFirstTraversal(1);
}
}
I am expecting the Depth First Traversal to start from A and follow the Depth First Traversal until the last element in the graph, but instead I am outputting this:
Depth First Traversal from first value:
A-1
I-9
Java is 0-indexed, meaning that arrays start at index 0. You were creating an array of size 10, but using the latter 9 entries. I changed your input data to match this, but it wasn't the issue.
public class GraphDemo {
public static void main(String args[]) {
Graph graph = new Graph(9);
graph.addEdge(0, 0);
graph.addEdge(1, 2);
graph.addEdge(2, 4);
graph.addEdge(3, 6);
graph.addEdge(4, 8);
graph.addEdge(5, 1);
graph.addEdge(6, 2);
graph.addEdge(7, 4);
graph.addEdge(8, 7);
graph.setLabels(0,9);
graph.setLabels(1,3);
graph.setLabels(2,5);
graph.setLabels(3,7);
graph.setLabels(4,4);
graph.setLabels(5,8);
graph.setLabels(6,6);
graph.setLabels(7,2);
graph.setLabels(8,1);
System.out.println("Depth First Traversal from first value: \n");
graph.depthFirstTraversal(1);
}
}
I'm not sure what labels are or mean, so I've ignored them completely along with the neighbors which iterates through these labels. Here's the depth first traversal either way:
private void depthFirstTraversal(int v, boolean[] visitedIndexes) {
if (visitedIndexes[v]) {
System.out.println("Arrived at index " + v +
" with letter " + (char) ('A' + v) +
" but we've already been here, so skipping this.");
return;
}
System.out.println("Traversing index " + v +
" which has label " + labels[v] +
" and here's some letter " + (char) ('A' + v)
);
visitedIndexes[v] = true;
for (int i = 0; i < n; i++) {
if (edges[v][i]) {
depthFirstTraversal(i, visitedIndexes);
}
}
}
I have written a polynomial class and a tester class. The polynomial class can evaluate and return the sum of the polynomial when the degree, coefficients and the value of x are provided. Basically I need to edit my toString method so it actually prints out the polynomial
import java.util.Arrays;
import java.util.Scanner;
public class Polynomial {
private int degree;
private int [] coefficient;
private double evaluation;
private double sum;
private double value;
Scanner key = new Scanner(System.in);
public Polynomial(int degree)
{
this.degree = degree;
coefficient = new int [degree+1];
}
public void setCoefficient(int coefficient)
{
this.coefficient[this.degree] = coefficient;
}
public int getCoefficient(int degree)
{
return coefficient[degree];
}
public double Evaluate(double value)
{
this.value =value;
for (int i=0; i<=degree; i++)
{
System.out.println("Enter coefficent for position " + i);
this.coefficient[i] = key.nextInt();
evaluation = Math.pow(value, i)*this.coefficient[0] ;
this.sum += evaluation;
}
return sum;
}
/** Standard toString method */
//needed something better than this below...needed an actual polynomial printed out
public String toString()
{
return "The degree of the polynomial is " + degree + " and the value for which it has been evaluated is" + value;
}
}
This should be along the lines you should be proceeding. I included the main function in your Polynomial class for simplicity, so you will have to modify that if you want to keep it in your tester class. Notice that degree has been made into an integer array of size degree +1(allocated in the constructor):
import java.util.Scanner;
public class Polynomial {
private int degree;
private int [] coefficient;
private double evaluation;
private double sum;
Scanner key = new Scanner(System.in);
public Polynomial(int degree)
{
this.degree = degree;
coefficient = new int [degree+1];
}
public void setCoefficient(int coefficient, int degree)
{
this.coefficient[degree] = coefficient;
}
public int getCoefficient(int degree)
{
return coefficient[degree];
}
public void Evaluate(double value)
{
for (int i=0; i<=degree; i++)
{
System.out.println("Enter coefficent for position " + i);
this.coefficient[i] = key.nextInt();
evaluation = Math.pow(value, i)*this.coefficient[0] ;
this.sum += evaluation;
}
}
public double getSum(){
return sum;
}
public String toString()
{
String s = "";
for (int i=0; i <= degree; i++)
{
s += coefficient[i];
switch (i) {
case 0:
s += " + ";
break;
case 1:
s += "x + ";
break;
default:
s += "x^" + i + ((i==degree)?"":" + ");
}
}
return s;
}
public static void main(String[] args) {
int degree;
double sum;
int coefficient;
Scanner key = new Scanner(System.in);
System.out.println("Enter the degree of the polynomial");
degree=key.nextInt();
Polynomial fun = new Polynomial(degree);
fun.Evaluate(3.0);
System.out.println(" The sum of the polynomial is " + fun.getSum());
System.out.println(fun);
}
}
The usual way of making the objects of a class printable is to supply a toString method in the class, which specifies how to express objects of that class as a String. Methods such as println and other ways of outputting a value will call a class's toString method if they need to print an object of that class.
You should adopt the same pattern with your Polynomial class - write a toString method with all the output logic. Then in your PolynomialTester class, all you need to write is System.out.println(fun); and the rest will just happen. You'll find this far more versatile than writing a method that actually does the printing. For example, you'll be able to write something like
System.out.println("My polynomial is " + fun + " and " + fun + " is my polynomial.");
if that's your idea of fun.
A few other things concern me about your class.
You seem to be only storing one coefficient and one exponent. I'd expect a polynomial to have a whole array of coefficients.
You have fields for evaluation and sum - but these only really make sense while a polynomial is being evaluated. They're not long-term properties of the polynomial. So don't store them in fields. Have them as local variables of the evaluate method, and return the result of the evaluation.
I'd expect a class like this to be immutable. That is, you should provide all the coefficients when the object is created, and just never change them thereafter. If you do it that way, there's no need to write setter methods.
So I've written my own version of your class, that fixes those issues listed above, and implements a toString method that you can use for printing it. A second version of toString lets you specify which letter you want to use for x. I've used "varargs" in the constructor, so you can construct your polynomial with a line such as
Polynomial fun = new Polynomial (7, 2, 5, 0, 1);
specifying the coefficients from the constant term through in order to the coefficient of the term with the highest exponent. Or you can just pass an array.
See that I've changed the logic a wee bit - my version prints the polynomial in the conventional order, from highest to lowest exponent. It leaves off the decimals if the coefficient is an integer. It doesn't print a 1 in front of an x. And it deals cleanly with - signs.
import java.util.Arrays;
public class Polynomial {
private double[] coefficients;
public Polynomial(double... coefficients) {
this.coefficients = Arrays.copyOf(coefficients, coefficients.length);
}
public int getDegree() {
int biggestExponent = coefficients.length - 1;
while(biggestExponent > 0 && coefficients[biggestExponent] == 0.0) {
biggestExponent--;
}
return biggestExponent;
}
public double getCoefficient(int exponent) {
if (exponent < 0 || exponent > getDegree()) {
return 0.0;
} else {
return coefficients[exponent];
}
}
public double evaluateAt(double x) {
double toReturn = 0.0;
for (int term = 0; term < coefficients.length; term++) {
toReturn += coefficients[term] * Math.pow(x, term);
}
return toReturn;
}
#Override
public String toString() {
return toString('x');
}
public String toString(char variable) {
boolean anythingAppendedYet = false;
StringBuilder toReturn = new StringBuilder();
for (int exponent = coefficients.length - 1; exponent >= 0; exponent--) {
if (coefficients[exponent] != 0.0) {
appendSign(toReturn, exponent, anythingAppendedYet);
appendNumberPart(toReturn, exponent);
appendLetterAndExponent(toReturn, exponent, variable);
anythingAppendedYet = true;
}
}
if (anythingAppendedYet) {
return toReturn.toString();
} else {
return "0";
}
}
private void appendSign(StringBuilder toAppendTo, int exponent, boolean anythingAppendedYet) {
if (coefficients[exponent] < 0) {
toAppendTo.append(" - ");
} else if (anythingAppendedYet) {
toAppendTo.append(" + ");
}
}
private void appendNumberPart(StringBuilder toAppendTo, int exponent) {
double numberPart = Math.abs(coefficients[exponent]);
if (numberPart != 1.0 || exponent == 0) {
//Don't print 1 in front of the letter, but do print 1 if it's the constant term.
if (numberPart == Math.rint(numberPart)) {
// Coefficient is an integer, so don't show decimals
toAppendTo.append((long) numberPart);
} else {
toAppendTo.append(numberPart);
}
}
}
private void appendLetterAndExponent(StringBuilder toAppendTo, int exponent, char variable) {
if (exponent > 0) {
toAppendTo.append(variable);
}
if (exponent > 1) {
toAppendTo.append("^");
toAppendTo.append(exponent);
}
}
}
So I tested it with this class
public class PolynomialTester {
public static void main(String[] args) {
Polynomial fun = new Polynomial (7, 2, 5, 0, 1);
System.out.println(fun.getDegree());
System.out.println(fun.evaluateAt(3));
System.out.println(fun);
}
}
and the output was
4
139.0
x^4 + 5x^2 + 2x + 7
then I realised that you wanted to be able to input the coefficients in a loop. So I changed PolynomialTester to this. See how I build the array and then create the object.
import java.util.Scanner;
public class PolynomialTester {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("Enter the degree:");
int degree = input.nextInt();
double[] coefficients = new double[degree + 1];
for( int exponent = 0; exponent <= degree; exponent++) {
System.out.println("Enter the coefficient of x^" + exponent);
coefficients[exponent] = input.nextDouble();
}
Polynomial fun = new Polynomial (coefficients);
System.out.println(fun.evaluateAt(3));
System.out.println(fun);
input.close();
}
}
Note that if you really want your polynomial to be printed in "reverse" order, with the constant term first, you could change the loop in the toString method to this.
for (int exponent = 0; exponent < coefficients.length; exponent++) {
You may add a class member String poly, then modify the following method.
public void Evaluate(double value)
{
for (int i=0; i<=degree; i++)
{
System.out.println("Enter coefficent for position " + i);
this.coefficient= key.nextInt();
evaluation = Math.pow(value, i)*coefficient ;
this.sum += evaluation;
this.poly = "";
if(coefficient != 0)
{
if(i > 0)
{
this.poly += " + " + Integer.toString(coefficient) + "x^" + Integer.toString(i); // you may replace x with the actual value if you want
}
else
{
this.poly = Integer.toString(coefficient)
}
}
}
}
This program is on Eclipse. I have to declare variables "Integer" not "int". When I am compiling this code shows no error but there is a runtime error. Please fix this problem.
Runtime error:
Exception in thread "main" java.lang.NullPointerException
at Polynomial.add(Polynomial.java:17)
at PolynomialTest.main(PolynomialTest.java:7)
Polynomial.java
public class Polynomial{
Integer coef[];
Integer exp;
public Polynomial(Integer a, Integer b) {
coef = new Integer[b+1];
coef[b] = a;
exp = b;
}
// return c = a + b
public Polynomial add(Polynomial b) {
Polynomial a = this;
Polynomial c= new Polynomial(0, Math.max(a.exp, b.exp));
for (Integer i = 0; i <= a.exp; i++){
c.coef[i] = c.coef[i] + a.coef[i];
}
for (int i = 0; i <= b.exp; i++){
c.coef[i] += b.coef[i];
}
return c;
}
public String toString() {
if (exp == 0){
return "" + coef[0];
}else
if (exp == 1){
return coef[1] + "x + " + coef[0];
}
String s = coef[exp] + "x^" + exp;
for (int i = exp-1; i >= 0; i--) {
if (coef[i] == 0){
continue;
}
else if (coef[i] > 0){
s = s + " + " + ( coef[i]);
}
if (i == 1){
s = s + "x";
}
else
if (i > 1) {
s = s + "x^" + i;
}
}
return s;
}}
PolynomialTest.java
public class PolynomialTest {
// test client
public static void main(String[] args) {
Polynomial p1 = new Polynomial(4, 4);
Polynomial p2 = new Polynomial(7, 2);
Polynomial p3 = new Polynomial(3, 0);
Polynomial p = p1.add(p2).add(p3); // 4x^3 + 3x^2 + 1
Polynomial q1 = new Polynomial(2, 2);
Polynomial q2 = new Polynomial(5, 4);
Polynomial q = q1.add(q2);
System.out.println("p(x) = " + p);
System.out.println("q(x) = " + q);
System.out.println("p(x) + q(x) = " + p.add(q));
}
}
Since Integer is an Object, you will need to initialize each entry in your coef array with a new Integer object.
You could just do this in the Polynomial constructor:
public class Polynomial{
Integer coef[];
Integer exp;
public Polynomial(Integer a, Integer b) {
coef = new Integer[b+1];
for (int i = 0; i < coef.length; i++){
coef[i] = new Integer(0); //create a new Integer and initialize to zero
}
coef[b] = a;
exp = b;
}