Another common student request is for class polynomial ...
Here is the polynomial.h file ... (followed by the test program file) ...
// polynomial.h // 2011-03-27 //
#ifndef POLYNOMIAL_H
#define POLYNOMIAL_H
#include <iostream>
#include <fstream>
#include <sstream> // to 'smooth' input from keyboard ...
#include <string>
#include <vector>
#include <cmath> // for pow( base, index )
//using namespace std;
using std::ostream;
using std::istream;
using std::istringstream;
using std::string;
using std::vector;
using std::cout;
using std::endl;
using std::flush;
// a simple way to dodge the overhead of defining a template <class T>
// polynomial here ...
typedef double my_type;
const int MAX_TERMS_ON_LINE = 8;
class polynomial
{
friend ostream& operator<< (ostream& os, const polynomial& p);
friend istream& operator>> (istream& os, polynomial& p);
public:
polynomial();
polynomial(int d);
polynomial( const polynomial& ); // copy constructor
int degree() const;
polynomial& operator= ( const polynomial& ); // assignment
polynomial& operator+= (const polynomial& p);
polynomial operator+ (const polynomial& p) const;
polynomial operator- () const; // unary operator ...
polynomial operator- (const polynomial& p) const;
polynomial& operator-= (const polynomial& p);
polynomial operator* (const polynomial& p) const;
polynomial dif() const;
polynomial antidif() const;
bool operator== (const polynomial& p) const;
my_type operator() (my_type x) const; // ... evaluate poly for this x
my_type& operator[] ( int i ) { return coefficients[i]; }
my_type operator[] ( int i ) const { return coefficients[i]; }
private:
vector < my_type > coefficients;
void trim()
{
int i, d = degree();
for( i = d; i >= 0; --i )
if( coefficients[i] != 0 ) break;
if( d - i ) coefficients.resize( i+1 );
}
};
// friend functions defined here ...
// Just enter zero for a coef. if that 'degree' does not exit (but a higher does)
// and ... just press 'Enter' to exit input loop ...
istream& operator>> (istream& is, polynomial& p)
{
int t=0;
my_type tmp;
string tmpStr;
p.coefficients.clear();
for( ;; )
{
cout << "Input coef[" << t++ << "]: " << flush;
getline( is, tmpStr );
if( t>1 && tmpStr == "" ) { --t; break; }
istringstream iss( tmpStr );
tmp = 0;
iss >> tmp;
p.coefficients.push_back( tmp );
}
int d = p.degree();
//don't allow leading terms with zero coeff's
if( d+1 != t ) p.coefficients.resize(d+1);
return is;
}
ostream& operator<< (ostream& os, const polynomial& p)
{
bool firstPassDone = false;
my_type coeff;
for(int c = 0, i = p.degree(); i >= 0; --i)
{
if(p[i] != 0 || (i == 0 && ! firstPassDone))
{
coeff = p[i];
if(coeff < 0) coeff = -coeff;
if(firstPassDone)
{
cout << ' ' << (p[i] < 0 ? '-' : '+') << ' ';
if(i == 0 || coeff != 1) { c++; os << coeff; }
}
else
{
if(i == 0 || coeff != 1) { c++; os << p[i]; }
else if(p[i] < 0) os << '-';
}
if(i > 0)
{
os << 'x';
if(i > 1) os << '^' << i;
}
firstPassDone = true;
}
if(c == MAX_TERMS_ON_LINE && i != 0) { c=0; os << endl; }
}
return os;
}
// Constructor: creates a zero polynomial with maximum degree 0.
polynomial::polynomial() : coefficients(1)
{
//coefficients = vector< my_type >(1);
//coefficients[0] = 0; // done by ctor above
}
// Constructor: creates a zero polynomial with maximum degree d.
polynomial::polynomial(int d) : coefficients(d+1)
{
//coefficients = vector< my_type >(d+1);
//for(int i = 0; i <= d; ++i) coefficients[i] = 0; // done by ctor above
}
// Constructor: copy constructor
polynomial::polynomial(const polynomial& p)
{
coefficients = p.coefficients; // uses vector =
}
// Member function to compute the real degree of a polynomial.
int polynomial::degree() const
{
for(int i = coefficients.size() - 1; i >= 0; --i)
if( coefficients[i] != 0 ) return i;
// if reach here ...
return 0;
}
// assignment ...
polynomial& polynomial::operator= (const polynomial& p)
{
if( this != &p ) // i.e. ... if NOT the same ...
{
coefficients = p.coefficients;
}
return *this;
}
// first define += ...
polynomial& polynomial::operator+= (const polynomial& p)
{
int a = degree();
int b = p.degree();
int i;
if( a >= b )
{
for( i=0; i<=b; ++i )
coefficients[i] = coefficients[i]+ p[i];
}
else
{
coefficients.resize(b+1);
for( i=0; i<=a; ++i )
coefficients[i] = coefficients[i] + p[i];
for( ; i<=b; ++i )
coefficients[i] = p[i];
}
return *this;
}
// then can easily do ...
polynomial polynomial::operator+ (const polynomial& p) const
{
polynomial tmp( *this );
return tmp += p;
}
// first define ...
// unary operator ... returns -values to all coeff's
polynomial polynomial::operator- () const
{
polynomial tmp( *this );
for( int i = coefficients.size()-1; i >= 0; --i )
tmp[i] = - coefficients[i];
return tmp;;
}
// then can easily do ...
polynomial polynomial::operator- (const polynomial& p) const
{
polynomial tmp( *this );
tmp = -p + tmp;
tmp.trim();
return tmp;
}
// and ...
polynomial& polynomial::operator-= (const polynomial& p)
{
*this += -p;
this->trim();
return *this;
}
polynomial polynomial::operator* (const polynomial& p) const
{
int a = degree();
int b = p.degree();
polynomial tmp(a+b);
for( int i=0; i<=a; ++i )
for( int j=0; j<=b; ++j )
tmp.coefficients[i+j] += coefficients[i] * p[j];
tmp.trim();
return tmp;
}
polynomial polynomial::dif() const
{
int a = degree();
if( a == 0 ) return polynomial(); // zero polynomial
polynomial tmp(a-1);
for( int i = a-1; i >=0; --i )
tmp[i] = (i+1)* coefficients[i+1];
return tmp;
}
polynomial polynomial::antidif() const
{
int a = degree();
polynomial tmp(a+1);
for( int i = a+1; i > 0; --i )
tmp[i] = coefficients[i-1]/double(i);
return tmp;
}
bool polynomial::operator== (const polynomial& p) const
{
int a = degree();
if( a != p.degree() ) return false;
for( int i=0; i<=a; ++i )
if( coefficients[i] != p[i] ) return false;
return true;
}
my_type polynomial::operator() (my_type x) const
{
my_type sum = 0;
for( int i = degree(); i >= 0; --i)
sum += coefficients[i]*pow( x, i );
return sum;
}
#endif