/*
*Daniel Tabuenca
*###-##-3128
*Login: dtabuenc
*Lab section 23
*Assignment 1
*Due April 28, Friday, 11:59pm, 2000
*/
#include <stdio.h>
#include <string.h>
#include "polynomial.h"
#define BUFFERSIZE 80
istream &operator>>(istream &in, Polynomial &poly)
{
if (!poly.terms.empty())
{
cerr<<"Polynomial already initialized!\n";
return in;
}
/*Buffer for reading in file*/
char buffer[BUFFERSIZE];
/*Character for storing trailing
*bracket to check for valid expression.
*/
char bracket;
/*variable to store polynomials
*we read from the file.
*/
PolyTerm newTerm;
/*Loop forever*/
for(;;)
{
/*Stop if no more lines to read*/
in.getline(buffer,80);
if(in.eof())
{
cerr<<"No valid Polynomial line found!\n";
return in;
}
/*Stop if we found what looks like a polynomial
*This is a simple regular expression search for
*any string surrounded by brackets. See the
*sscanf man page for more details
*/
if(sscanf(buffer, " [ %[^]] %c",buffer,&bracket)==2)
{
if(bracket==']')
break;
else
continue;
}
}
/*Keep reading in terms until we find no comma*/
for(;;)
{
if(sscanf(buffer, " %f ( %f )", &(newTerm.base), &(newTerm.exp))<2)
{
cerr<< "Malformed input!\n";
return in;
}
/*Add the term to the linked list*/
poly.terms.push_back(newTerm);
/*Shrink the string down to what is after
*the next comma. If there is no next comma
*then there is no next element and we are
*done.
*/
if(sscanf(buffer, " %*f ( %*f ) , %[^a-Z]", buffer)!=1)
{
/*We are done inputting new terms so
*sort the list just for fun and then
*return.
*/
poly.terms.sort();
/*Also simplify the polynomial
*so all other algorithms will
*run faster.
*/
poly.simplify();
return in;
}
}
}
/*Outputs the polynomial in specified format*/
ostream &operator<<(ostream &out, Polynomial &poly)
{
/*Check if we have terms in the polynomial*/
if(poly.terms.empty())
{
cerr<<"Attempt to print uninitialize Polynomial\n";
return out;
}
/*Set of iterators to traverse the linked
*list. The begin and end operator
*are just for speed to avoid a function
*call every time we need to check if
*we are at the beginning or end.
*/
TermListIterator term;
TermListIterator begin=poly.terms.begin();
TermListIterator end=poly.terms.end();
/*We start with the open bracket*/
out << "[";
/*Go through the entire list printing each term*/
for(term=poly.terms.begin(); term!=end; term++)
{
/*Don't output the comma the first time*/
if(term!=begin)
out <<", ";
out << *term;
}
/*End with a bracket*/
out << "]";
return out;
}
/*Simplify assumes it has been given
*a sorted list of terms and goes through
*efficiently combining like terms.
*/
void Polynomial::simplify()
{
TermListIterator currTerm;
TermListIterator nextTerm;
TermListIterator begin=terms.begin();
TermListIterator end=terms.end();
/*Set the first two terms to be checked*/
currTerm=begin;
nextTerm=begin;
nextTerm++;
/*We will go through the whole list*/
while(nextTerm!=end)
{
/*If the exponent match we can combine them*/
if( (*currTerm).exp == (*nextTerm).exp )
{
/*Add the base of the current one
*to the base of the next one*/
*nextTerm+= *currTerm;
/*We can now delete the current one
*(the return value is the iterator
*following the deleted one so we don't
*have to increment currTerm.
*/
currTerm=terms.erase(currTerm);
/*Move the next iterator up one too.
*/
nextTerm++;
continue;
}
/*We didn't find any match so move both
*up by one and try again.
*/
currTerm++;
nextTerm++;
}
}
/*Add two polynomials returning a pointer to a newly
*created polynomial.
*/
Polynomial *Polynomial::operator+(Polynomial &oldPoly)
{
Polynomial *newPoly= new Polynomial;
Polynomial *oldBackup= new Polynomial;
TermListIterator copyer;
/*We first copy one of the polynomials to what will
*be the final result.
*/
for(copyer=terms.begin(); copyer!=terms.end();copyer++)
{
newPoly->terms.push_back(*copyer);
}
/*Back up the other one so it won't get erased*/
for(copyer=oldPoly.terms.begin(); copyer!=oldPoly.terms.end();copyer++)
{
oldBackup->terms.push_back(*copyer);
}
/*Merge the two sorted lists*/
newPoly->terms.merge(oldBackup->terms);
/*Combine like terms*/
newPoly->simplify();
/*clean up memory*/
delete oldBackup;
return newPoly;
}
/*Multiply an entire polynomial by a single term,
*returning a new polynomail.
*/
Polynomial *Polynomial::operator*(PolyTerm &oldTerm)
{
Polynomial *newPoly=new Polynomial;
PolyTerm newTerm;
TermListIterator currTerm;
TermListIterator end=terms.end();
/*We add to the new list each element of the
*old list multiplied by the term.
*/
for(currTerm=terms.begin(); currTerm!=end;currTerm++)
{
newTerm= *currTerm;
newTerm*=oldTerm;
newPoly->terms.push_back(newTerm);
}
return newPoly;
}
/*Multiply two polynomials, returning the new polynomial
*as a pointer.
*/
Polynomial *Polynomial::operator*(Polynomial &oldPoly)
{
/*First figure out the smaller polynomial (less
*terms) in order to speed up the algorithm.
*/
Polynomial *bigger, *smaller;
if(this->terms.size()>oldPoly.terms.size())
{
bigger=this;
smaller=&oldPoly;
}
else
{
bigger=&oldPoly;
smaller=this;
}
/*For each term in the small polynomial we will create a new polynomial
*so allocate an array of Polynomial Pointers for this purpose.
*/
Polynomial **mergeArray=new (Polynomial *)[smaller->terms.size()];
/*Iterators to go through two polynomials*/
TermListIterator smallIter,bigIter;
/*Temporary holding place for term processing*/
PolyTerm newTerm;
int i=0;
/*For each term in the smaller polynomial*/
for(smallIter=smaller->terms.begin();smallIter!=smaller->terms.end();smallIter++)
{
/*Create a new polynomial*/
mergeArray[i]=new Polynomial;
/*For each term in the bigger polnomial*/
for(bigIter=bigger->terms.begin();bigIter!=bigger->terms.end();bigIter++)
{
/*Get the term*/
newTerm = *bigIter;
/*Multiply by the term in the smaller
*poly.
*/
newTerm *= *smallIter;
/*Add the result to the new polynomial*/
mergeArray[i]->terms.push_back(newTerm);
}
i++;
}
/*Create the actual new polynomial we will return.
*/
Polynomial *newPoly=new Polynomial;
/*Set it equal to the first Polynomial in the array*/
*newPoly=*mergeArray[0];
/*Delete first polynomial from the array*/
delete mergeArray[0];
/*go through the array of polynomials (i is used from
*above as it contains the size of the array.
*/
for(int j=1; j<i; j++)
{
/*Merge the terms of the array to the new
*Polynomial.
*/
newPoly->terms.merge(mergeArray[j]->terms);
/*Delete each term as we don't need it anymosr*/
delete mergeArray[j];
}
/*Delete the entire array*/
delete [] mergeArray;
/*Combine like terms*/
newPoly->simplify();
return newPoly;
}
syntax highlighted by Code2HTML, v. 0.8.11