Beginner polynomial program in C++

2019-07-18 17:10发布

I'm looking for some assistance on an exercise for my C++ programming class. Unfortunately, I was rather ill this week and unable to attend class, meaning I have only been able to use the textbook as a resource, so I'm pretty lost when it comes to writing this program. Therefore, I figured I'd turn to the real pros here for assistance. I realize this is broad, but any help and/or tips would be appreciated. Here are the instructions we were given:

This assignment deals with representing and manipulating polynomials using simple arrays. A polynomial, such as anxn + an-1xn-1 + … + a0, will be implemented as an array of coefficients, with >coefficient ai being stored in location i of the array. The coefficients are floating point values (potentially negative), so we will use an array of type double. The array will be of size MAXPOLY (a constant variable set to 50) and so we will be limited to holding polynomials with maximum degree of MAXPOLY – 1 (or 49).

The file Poly.h describes all the functions provided by the class.

You are to implement the following set of functions:
- Default constructor to initialize a polynomial to the zero polynomial
- setCoeff to set a specific coefficient in the polynomial
- retrieveCoeff to get a specific coefficient from the polynomial
- incrementCoeff to add a value to a specific coefficient in the polynomial
- degree which determines the degree of the polynomial
- numOfTerms which determines the number of terms in the polynomial (i.e., how many array elements are nonzero)
- evaluate which evaluates the polynomial for a given value of X
- add which adds one polynomial to another, changing the polynomial added to
- derivative which computes the derivative of a polynomial
- equals which determines the equality of two polynomials

Several functions are provided for you: (1) a toString function will be provided to you so that >all our polynomials will be displayed identically, (2) the insertion operator is defined so we can >easily print a polynomial, and (3) the equality, inequality, and addition operators are provided >and are simply defined in terms of your equals and add functions. You should not change any of the provided functions.

You will be supplied two starter files, Poly.cpp and Poly.h. The class declaration file Poly.h contains a complete specification of a class named Poly. Your task will be to implement >all the specified functions in the class definition file Poly.cpp (with the exception of the few >functions which have been provided for you.). You have also been provided with an initial test >program PolyTest.cpp. You should add code to the PolyTest.cpp file to fully test your Poly class(copy code from the PolyTest.cpp file you created for Project #1-Pre).

We were, indeed, supplied those files. The Poly.h file looks like this:

#define POLY_H
#ifndef POLY_H
#include <string>
using namespace std;

const size_t MAXPOLY = 50;    

class Poly
{

private:
    // Data members   [implementation of ADT's data object]

    // array for holding the coefficients of the poly
    double coeff[MAXPOLY];               
public:

    // Default Class constructor: initializes a polynomial to the constant 0
    // note: all array elements of coeff[] must be set to 0.0  
    Poly ();

    // degree: finds the degree of a polynomial (the highest power with a non-zero coefficient)
    size_t degree () const;

    // setCoeff: sets a term, value*x^i, in a polynomial
        // Throws <std::out_of_range> if index i does not meet the precondition.
    void setCoeff (double value, size_t i);

    // retrieveCoeff: finds the coefficient of the x^i term in poly
    // Throws <std::out_of_range> if index i does not meet the precondition.
    double retrieveCoeff (size_t i) const;

    // incrementCoeff: changes a term, value*x^i, in a polynomial
    // Throws <std::out_of_range> if index i does not meet the precondition.
    void incrementCoeff(double value, size_t i);

    // toString: produce a string representation of a Poly object
    // note: This function has been provided for you -- DO NOT CHANGE IT!
    string toString() const;

    // numOfTerms: returns the number of terms in the polynomial.
    size_t numOfTerms () const;

    // evaluate: evaluate a polynomial for a specified value of X
    double evaluate (double x) const;

    // add: add one polynomial to another
    void add (const Poly& aPoly);

    // addition operator: add two polynomials together and return a new polynomial that is the result
    // note: This function has been provided for you -- DO NOT CHANGE IT!
    Poly operator+ (const Poly& rhs) const;

    // equals: determine if two polynomials are equal
    bool equals (const Poly& aPoly) const;

    // Equality/inequality operators
    // note: These functions have been provided for you -- DO NOT CHANGE IT!
    bool operator== (const Poly& rhs) const;
    bool operator!= (const Poly& rhs) const;

    // derivative: compute the derivative of a polynomial
    void derivative ();

    // insertion operator for output
    // note: This function has been provided for you -- DO NOT CHANGE IT!
    friend ostream& operator<< (ostream& os, const Poly &p);
};  

#endif

The Poly.cpp file looks like this:

#include <iostream>
#include <sstream>
#include <stdexcept>
#include <cmath>
#include "Poly.h"
using namespace std;


// Class constructor
Poly::Poly ()
{
    //ADD YOUR CODE HERE
}

// degree
size_t Poly::degree() const
{
    //ADD YOUR CODE HERE
}

// setCoeff
void Poly::setCoeff (double value, size_t i)
{
    // ADD YOUR CODE HERE
}

// retrieveCoeff
double Poly::retrieveCoeff (size_t i) const
{
    return 0;    // REPLACE WITH YOUR CODE
}

// incrementCoeff
void Poly::incrementCoeff(double value, size_t i)
{
    // ADD YOUR CODE HERE
}

// toString
string Poly::toString() const
{
    ostringstream result;
    bool printedSomething = false;
    for (int i=(int)degree(); i>=0; i--) 
    {
          double c = retrieveCoeff(i);
          if (c != 0.0) 
      {
          printedSomething = true;
          if (i == 0) 
      {
              result.setf(ios::showpos);
              result << " " << c;
              result.unsetf(ios::showpos);
          }
          else 
      {
              result.setf(ios::showpos);
              result << " " << c;
              result.unsetf(ios::showpos);
              result << "*X^" << i;
          }
          }
      }
    if (!printedSomething) 
    {
        result.setf(ios::showpos);
        result << " " << 0;
        result.unsetf(ios::showpos);
    }
    return result.str();
}


// numOfTerms
size_t Poly::numOfTerms () const
{
    return 0;   // REPLACE WITH YOUR CODE
}

// evaluate
double Poly::evaluate (double x) const
{
    return 0;   // REPLACE WITH YOUR CODE
}

// add
void Poly::add (const Poly& aPoly)
{
    // ADD YOUR CODE HERE
}

// addition operator
Poly Poly::operator+ (const Poly& rhs) const
{
    Poly result;
    result.add(*this);
    result.add(rhs);
    return result;
}

// equals
bool Poly::equals (const Poly& aPoly) const
{
    return false;   // REPLACE WITH YOUR CODE
}

// Equality/inequality operators
bool Poly::operator== (const Poly& rhs) const
{
    return equals(rhs);
}

bool Poly::operator!= (const Poly& rhs) const
{
    return !equals(rhs);
}

// derivative
void Poly::derivative ()
{
    // ADD YOUR CODE HERE
}

// Friend operator for printing a Poly object.
ostream & operator << (ostream &out, const Poly& p)
{
    out << p.toString();
    return out;
}

#endif

Although I have a basic understanding of C++, this is only the second week of classes (apparently a bad one to miss), so I am still in the learning stages. Any help, even if it is just a place to start, would be greatly appreciated. Thank you!

Note: I am compiling in Microsoft Visual Studio if that is of any help

1条回答
一纸荒年 Trace。
2楼-- · 2019-07-18 17:48

Couple of things with your posted code.

  1. You need to switch the following lines in Poly.h:

    #define POLY_H
    #ifndef POLY_H
    

    Otherwise, nothing from the file gets included.

  2. It's a bad practice to use

    using namespace std;
    

    in a .h file. Use explicit type names, such as std::string and std::ostream.

Coming to your main obstacle, you have to figure out how to implement the functions in Poly.cpp. You can use a test driven approach to flesh out the contents of the file.

Let's say you have a file named TestPoly.cpp. The file contains the main function and drives testing of the implementation of Poly.

You can start with:

void testSetCoeff();

int main()
{
   testSetCoeff();
   return 0;
}

How would you implement testSetCoeff?

Here's something to start off:

void testSetCoeff()
{
   std::cout << "Testing setCoeff()/retrieveCoeff(): ";

   // Construct an instance of Poly.
   Poly p;

   // Set the 0-the coefficient.       
   p.setCoeff(1.0, 0);

   // Retrieve the same coefficient.
   double c = p.retrieveCoeff(0);

   // Make sure that we get the same value.
   if ( almostEqual(c, 1.0) )
   {
      std::cout << "SUCCESS\n";
   }
   else
   {
      std::cout << "FAILURE\n";
   }
}

The strategy followed in the function:

  1. Set some data on an object.
  2. Retrieve the data from the same object.
  3. Make sure that you get back a value that makes sense. Add an appropriate test for it.

In the function above, I chose to use

   if ( almostEqual(c, 1.0) )

instead of

   if ( c == 1.0 )

to make sure that we are able to deal with the inexact nature of floating point representations.

The implementation of almostEqual is something like:

bool almostEqual(double x, double y)
{
   static double const tolerance = 1.0E-6;
   return (fabs(x-y) < tolerance);
}

Putting these all together, the content of the starter version of TestPoly.cc will be:

#include "Poly.h"

#include <iostream>
#include <cmath>

bool almostEqual(double x, double y);
void testSetCoeff();

int main()
{
   testSetCoeff();
   return 0;
}

bool almostEqual(double x, double y)
{
   static double const tolerance = 1.0E-6;
   return (fabs(x-y) < tolerance);
}

void testSetCoeff()
{
   std::cout << "Testing setCoeff()/retrieveCoeff(): ";

   // Construct an instance of Poly.
   Poly p;

   // Set the 0-the coefficient.       
   p.setCoeff(1.0, 0);

   // Retrieve the same coefficient.
   double c = p.retrieveCoeff(0);

   // Make sure that we get the same value.
   if ( almostEqual(c, 1.0) )
   {
      std::cout << "SUCCESS\n";
   }
   else
   {
      std::cout << "FAILURE\n";
   }
}

With the current state of Poly.cpp, you will get FAILURE status. Now you can go to Poly.cpp and figure out how to change the implementations of setCoeff and retrieveCoeff to make that test pass.

// setCoeff
void Poly::setCoeff (double value, size_t i)
{
   coeff[i] = value;
}

// retrieveCoeff
double Poly::retrieveCoeff (size_t i) const
{
   return coeff[i];
}

Then, you can start adding other tests. They will most likely fail first. Then you implement the necessary functions until those tests pass.

Update, in response to OP's comment

The coefficients can be initialized to 0 in the constructor using memset.

Poly::Poly ()
{
   memset(coeff, 0, sizeof(coeff));
}

P.S.: Remember to #include cstring to use memset.

查看更多
登录 后发表回答