//! Please add relevant documentation
import java.util.regex.Pattern;
import java.util.regex.Matcher;
/**
* create a polynomial using the Term class(which represents a single term in the polynomial)
* @author Kristen Watson
* @version 10/20/13
*/
public class Polynomial {
// The polynomial is represented by an array of 'Term' instances.
// The 'terms' array may contain extraneous cells: the relevant cells
// are those from 0 through 'nTerms - 1'
private Term terms[]; // array of terms
private int nTerms; // number of meaningful terms
// default constructor: sets the instance to the zero polynomial
public Polynomial() {
nTerms = 0;
terms = new Term[1];
}
private Polynomial(int maxTerms) {
nTerms = 0;
terms = new Term[maxTerms];
}
public Polynomial(Polynomial p) {
nTerms = p.nTerms;
terms = new Term[nTerms];
for (int k = 0; k < nTerms; k++){
terms[k] = p.terms[k];
}
}
public Polynomial( String src ) {
// Initialize this polynomial to zero
nTerms = 0;
terms = new Term[1];
// Setup the basic regular expressions for matching terms
String xPatString = "x(\\^([0-9]))?";
Pattern termPattern =
Pattern.compile("\\s*(" + xPatString + ")" + "|"
+ "\\s*([-+]?[0-9]+(\\.[0-9]*)?)[ \\s]?(" + xPatString + ")?");
Pattern signPattern = Pattern.compile("\\s*([-+])\\s*");
// Match a sequence of signs and terms
Matcher matcher; // reassigned as needed for matching the patterns
int sign = 1; // incoming sign from the operator
while (true) {
Term term = new Term();
// The next thing in 'src' should be a term
matcher = termPattern.matcher(src);
boolean result = matcher.lookingAt();
if (!result) {
// syntax error: stop with what he have
break;
}
/* // Uncomment this to show the capture groups
* for (int k = 0; k < 9; k++)
* System.out.println("group " + k + ": " + matcher.group(k));
* System.out.println("");
*/
// extract the coefficient and power from the captured groups
if (matcher.group(1) != null) {
// group 1 contains the first alternation, which matches
// just "x^<power>" without a coefficient
term.coeff = sign;
if (matcher.group(2)== null) {
// the power is 1
term.power = 1;
}else {
// the power is in group 2
term.power = Integer.valueOf(matcher.group(2));
}
}else {
// otherwise, the second alternation matches, which has an
// explicit coefficient but an optional "x" term
term.coeff = sign*Double.valueOf(matcher.group(4));
// get the exponent
if (matcher.group(6) == null) {
// the "x" term is omitted; take it as x^0
term.power = 0;
}
else if (matcher.group(7) == null) {
// the exponent is omitted, take it as 1
term.power = 1;
}else {
term.power = Integer.valueOf(matcher.group(8));
}
}
// update the position in the input string
src = src.substring(matcher.end());
// add the term
if (nTerms >= terms.length) {
Term newTerms[] = new Term[2*nTerms];
for (int k = 0; k < terms.length; k++){
newTerms[k] = terms[k];
}
terms = newTerms;
}
terms[nTerms++] = term;
// If there is a "+" or "-", take it as a binary operator
// (which indicates there is another term coming)
matcher = signPattern.matcher(src);
if (matcher.lookingAt()) {
sign = (matcher.group(1).equals("-") ? -1 : 1);
src = src.substring(matcher.end());
}else {
break;
}
}
normalize();
}
/* Simple accessors */
/**
* Returns the degree of this polynomial, which is the largest power
* of all the terms.
* @return the degree
*/
public int degree() {
//! Implement
int degree = 0;
for(int i = 0; i < nTerms-1; i++){
if(terms[i].power > terms[i+1].power){
degree = terms[i].power;
}else{
degree = terms[i+1].power;
}
}
return degree;
}
/**
* Return true if this polynomial is zero
* @return true or flase
*/
public boolean isZero() {
//! Document and Implement
//! (should return true if, and only if, this polynomial is zero)
int numberZeros = 0;
for(int i = 0; i < nTerms; i++){
if(terms[i].coeff == 0){
numberZeros++;
}
}
if(numberZeros == nTerms){
return true;
}else{
return false;
}
}
/* Polynomial operations. */
/**
* Computes the polynomial sum of this polynomial and 'addend'.
* Neither this polynomial nor 'addend' is modified.
*
* @param addend polynomial to be added
* @return a newly created Polynomial instance containing the sum
*/
public Polynomial add( Polynomial addend ) {
//! It should go something like this
// Create a new polynomial for the sum
Polynomial sum = new Polynomial(nTerms + addend.nTerms);
// Copy the terms of this polynomial to the new 'sum' polynomial
int i = 0; // index of the term copied to the sum
for (int k = 0; k < nTerms; k++) {
sum.terms[i++] = new Term(terms[k]);
}
// Append all the terms of 'addend' to 'sum' after the terms of 'this'
for (int k = 0; k < addend.nTerms; k++) {
sum.terms[i++] = new Term(addend.terms[k]);
}
// Set the total number of terms
sum.nTerms = i;
// Normalize
sum.normalize();
return sum;
}
public void addTo( Polynomial addend ) {
//! Document and implement
// terms[i
}
/**
* Computes the polynomial difference of this polynomial and 'subtrahend'.
* Neither this polynomial nor 'subtrahend' is modified.
*
* @param subtrahend polynomial to be subtracted
* @return a newly created Polynomial instance containing the difference
*
public Polynomial sub( Polynomial subtrahend ) {
//! Implement;
return
}
*/
public void subFrom( Polynomial subtrahend ) {
//! Document and Implement
}
/**
* Computes the polynomial product of this polynomial and 'multiplier'.
* Neither this polynomial nor 'multiplier' is modified.
*
* @param multiplier polynomial to multiply by
* @return a newly created Polynomial instance containing the product
*
public Polynomial mul( Polynomial multiplier ) {
//! Implement
}
*/
public void mulBy( Polynomial multiplier ) {
//! Document and Implement
}
/**
* Computes this polynomial raised to the power 'power', which is the
* polynomial product of 'power' copies of this.
* @param power power to which this polynomial is raised (assumed to be
* nonnegative)
* @return a newly created polynomial instance containing the power
*/
public Polynomial pow( int power ) {
//! Implement
Polynomial returnable = new Polynomial(nTerms);
for(int i = 0; i < nTerms; i++){
returnable.terms[i] = terms[i];
}
if(power > 0){
for(int i = 0; i < nTerms; i++){
returnable.terms[i].power = (returnable.terms[i].power)*power;
}
}
return returnable;
}
/**
* Compares this polynomial and 'poly'. The return is true if they
* are equal as polynomials, and false otherwise
* @param poly polynomial instance to which this is compared
* @return true if the polynomials are equal, and false otherwise.
*
public boolean equals( Polynomial poly ) {
//! Implement
}
*/
/**
* delete term[index] from array and shift all terms following it to the left
* @param index
*/
public void delete(int index){
if(index < 0 || index >= nTerms){
System.out.println("Error deleting term from array");
System.exit(0);
}
for(int i = index; i < nTerms; i++){
terms[i] = terms [i+1];
nTerms--;
}
}
/* This method does much of the work. In this context, a polynomial
* is said to be "normalized" if each of the following holds
*
* 1. No two cells in the 'term' array have the same power
* 2. No cells have zero coefficients
* 3. The 'term' cells are sorted by increasing order of power
*/
private void normalize() {
//! Implement
int highestTerm = degree();
Term [] temp = new Term [nTerms]; //temporary array for sorting terms
int tempCounter = 0; //keep track of where terms are going into the temp[]
int similarPower = 0; //how many terms match the current power (p)
int shiftingTerms = 0; //keep track of current term while combining like terms
int tempCoeff = 0; //placeholder to add up coeff while combining like terms
int numberToDelete = 0; //how many terms need to be deleted from array
//sort terms[] into temp[] by lowest power to highest
for(int p = 0; p <= highestTerm; p++){
for(int n = 0; n < nTerms; n++){
if(terms[n].power == p){
temp[tempCounter] = terms[n];
tempCounter++;
}
}
}
//transfer temp[] back to terms []
for(int i = 0; i < nTerms; i++){
terms[i] = temp[i];
}
//combine like terms
for(int p = 0; p < highestTerm; p++){
for(int i = 0; i <nTerms ; i++){ //loop though temp[] to check to similarities in power
if(terms[i].power == p){ //if term[index].power is equal to p, increment similarPower
similarPower++;
}
}
if (similarPower < 1){ //similarPower == 0
//nothing?
}else if (similarPower < 2){ //similarPower == 1
shiftingTerms++; //increment to show that we are now looking at the next array (and the next power)
}else{ //similarPower is 2 or more, combine terms
for(int t = 1; t < similarPower; t++){ //total up all similar terms inside the temp[takeFromTemp]
terms[shiftingTerms].coeff = terms[shiftingTerms].coeff + terms[shiftingTerms+1].coeff;
numberToDelete++;
}
shiftingTerms++;
for(int d = 0; d < numberToDelete; d++){
delete(shiftingTerms);
}
}
similarPower = 0;
numberToDelete = 0;
}
nTerms++;
}
/**
* Returns a string representation of this polynomial
* @return string representation of this polynomial
*/
public String toString(){
//! Implement
//normalize();
String returnStatement = " "; //holder
for(int i = 0; i < nTerms; i++){
//put plus/minus in before each term, how will this effect 1st term?
if(i<1){
}else{
if(terms[i].coeff < 0){
returnStatement = returnStatement + (" - ");
}else{
returnStatement = returnStatement + (" + ");
}
}
//can toString method for Term be used inside this???????????
if(terms[i].coeff > 0){ //is constant greater than 0?
if(terms[i].power < 2){ //if power is 1, will be just x, not x^1
if(terms[i].power < 1 ){ //if power is 0, no x, just the constant
returnStatement = returnStatement + (terms[i].coeff );
}else{ //if power is 1, st coeff & x
returnStatement = returnStatement + (terms[i].coeff + "*x");
}
}else{ //if power is greater than 2
returnStatement = returnStatement + (terms[i].coeff + "*x^" + terms[i].power );
}
}else if(terms[i].coeff < 0){
if(terms[i].power < 2){ //if power is 1, will be just x, not n^1
if(terms[i].power < 1 ){ //if power is 0, no x, just the constant
returnStatement = returnStatement + (terms[i].coeff );
}else{ //if power is 1, st coeff & x
returnStatement = returnStatement + (terms[i].coeff + "*x");
}
}else{ //if power is greater than 2
returnStatement = returnStatement + (terms[i].coeff + "*x^" + terms[i].power );
}
}else{ //if constant/coeff is less 0
if(terms[i].power < 2){ //if power is 1, will be just x, not n^1
if(terms[i].power < 1){ //if power is 0, no x, just the constant
returnStatement = returnStatement + (0 );
}else{ //if power is 1, just coeff & x
returnStatement = returnStatement + ("x" );
}
}else{ //if power is greater than 2
returnStatement = returnStatement + ("x^" + terms[i].power );
}
}
}
return returnStatement;
}
}