0

我正在编写多项式类并重载了 + 运算符。前几天我问了一个关于实际超载过程的问题,得到了很好的回答。但是,我现在的问题是关于我的程序的实际功能。

我需要将两个用户输入的多项式加在一起。当一个多项式相加时,即使两个多项式大小不同,也只能相加。如果第一个输入的多项式大于第二个,我的程序可以正常运行,但如果第一个多项式小于第二个,我的程序会出错。更具体地说......我注意到它似乎留下了一个学期。最重要的是,它似乎将两个相似的项加在一起,然后用不同的指数打印出来。例如:2x^3 + 3x^3 = 5x^2。

作为参考,这是我之前关于这个程序的问题:Overloading + operator with classes contains array pointers (C++)

一些帮助将不胜感激。

我的代码:

#include<iostream>
#include<stdexcept>
using namespace std;

#ifndef POLYNOMIAL_H
#define POLYNOMIAL_H

class Polynomial 
{
      friend istream& operator>>(istream& in, Polynomial& p);
      friend ostream& operator<<(ostream& out, const Polynomial& p);
      public:
             Polynomial(int = 10);
             ~Polynomial();
             void assignExponent();
             Polynomial operator+(const Polynomial& other);

      private:
              int SIZE;
              int *exponents;
              int *polyPtr; 
};

#endif

//CONSTRUCTOR
Polynomial::Polynomial(int arraySize)
{
     if(arraySize > 0)
                  SIZE = arraySize;
     else
     {
         cout << "Array size must be greater than 0. Program will now "
              << "Terminate..." << endl;

         system("pause");
         exit(0);
     }

     polyPtr = new int[SIZE]; 
     exponents = new int[SIZE];

     for(int i = 0; i<SIZE; i++)
             polyPtr[i] = 0;

     assignExponent();
};

//DESTRUCTOR
Polynomial::~Polynomial() 
{
     delete [] polyPtr;                         
};

//STREAM INSERTION
istream& operator>>(istream& in, Polynomial& p)
{
         for(int i = 0; i<p.SIZE; i++)
         {
               in >> p.polyPtr[i];         
         }

         return in;
};

//STREAM EXTRACTION
ostream& operator<<(ostream& out, const Polynomial& p)
{
         int exponent;
         for(int i = 0; i<p.SIZE; i++)
         {
               exponent = (p.SIZE - 1) - i;

               if(p.polyPtr[i] != 1)
               {  
                  if(exponent > 0 && exponent != 1)
                           out << p.polyPtr[i] << "x^" << exponent << " + ";  

                  if(exponent == 1)
                           out << p.polyPtr[i] << "x" << " + ";

                  if(exponent == 0)
                           out << p.polyPtr[i];  
               }

               //In order to not display coefficient if = 1
               else
               {
                   if(exponent > 0 && exponent != 1)
                           out << "x^" << exponent << " + ";  

                   if(exponent == 1)
                           out << "x" << " + ";

                   if(exponent == 0)
                           out << p.polyPtr[i];
               }    
         }       

         return out;
}; 

//Assigns a value for exponent
void Polynomial::assignExponent()
{
     for(int i = 0; i<SIZE; i++)
     {
             exponents[i] = (SIZE - 1) - i;        
     }
};

//OVERLOAD OF + OPERATOR
Polynomial Polynomial::operator+(const Polynomial& other)
{
         Polynomial sum(SIZE);
         int difference;

         //If the first polynomial is larger
         if (SIZE > other.SIZE)
         {
            difference = SIZE - other.SIZE;

            for(int i = 0; i<SIZE; i++)
            {
                 if(i - difference < 0)
                      sum.polyPtr[i] = polyPtr[i];

                 else
                 {
                     sum.polyPtr[i] = polyPtr[i] + 
                                  other.polyPtr[i - difference];  
                 }                            
            }         
         }

         //If the second polynomial is larger       **PROBLEM***************************************  
         if(other.SIZE > SIZE)
         {
            difference = other.SIZE - SIZE;

            for(int i = 0; i<other.SIZE; i++)
            {
                 if(i - difference < 0)
                      sum.polyPtr[i] = other.polyPtr[i];

                 else
                 {
                     sum.polyPtr[i] = other.polyPtr[i] + 
                                  polyPtr[i - difference];  
                 }                            
            }         
         }

         //If the polynomials are equal
         if(SIZE == other.SIZE)     
         {
                  for(int i = SIZE-1; i >= 0; i--)
                  {
                          sum.polyPtr[i] = polyPtr[i] + other.polyPtr[i];        
                  }   
         }

         return sum;
};

int main()
{
    int polySize;

    //User enters a size for the first & second polynomial
    cout << "Enter a size for the first polynomial: ";
    cin >> polySize;
    Polynomial pOne(polySize);

    cout << "\nEnter a size for the second polynomial: ";
    cin >> polySize;
    Polynomial pTwo(polySize);

    //User enters in values (Overload of >> operator
    cout << "\n\nEnter in values for the first polynomial, "
         << "in the format - (x x x x): " << endl;
    cin >> pOne;
    cout << "\nEnter in values for the second polynomial, "
         << "in the format - (x x x x): " << endl;
    cin >> pTwo;

    //Overload << operator for output
    cout << "\nPolynomial 1 is: " << pOne << endl
         << "Polynomial 2 is: " << pTwo << endl;

    Polynomial pThree = pOne + pTwo;

    cout << "\nAfter being added together, the new polynomial is: "
         << pThree << endl;

 system("pause");   
}

输出窗口: 在此处输入图像描述

4

4 回答 4

4

的应该是两个多项式SIZE中的最大值:sumSIZE

Polynomial Polynomial::operator+(const Polynomial& other)
{
         Polynomial sum( max(SIZE,other.SIZE) );

否则,您的新多项式仅与您正在对其进行操作的多项式一样大,并且您将在循环的下方写入未分配的内存:

for(int i = 0; i<other.SIZE; i++)
{
     if(i - difference < 0)
          sum.polyPtr[i] = other.polyPtr[i];

     else
     {
         sum.polyPtr[i] = other.polyPtr[i] + 
                      polyPtr[i - difference];  // i may be higher than SIZE, thus sum.polyPtr[i] invokes undefined behaviour.
     }                            
}  
于 2013-03-15T13:37:29.497 回答
4

当前的第一个问题在这里:

 Polynomial sum(SIZE);

更好的:

 Polynomial sum(std::max(SIZE, other.SIZE));

但我认为真正的问题是你需要简化你的设计。首先可以使用:

      private:
              int    SIZE;
              double *coef;
};

简单地保持 ax^n in 的系数coef[n]=a。现在很容易找出您需要添加的元素。

但更简单的可能是用于 std::map<int,double> p;存储所有内容。p[n]=a;

没有调试和优化,只是一个想法:

      private:
             std::map<int,double> p; 
};

忘记任何new,delete和索引超出范围。

+() 将类似于:

Polynomial Polynomial::operator+(const Polynomial& other)
{
   Polynomial sum;  // No SIZE more.
   sum.p= p;
   for (auto ax_n : other.p)
      sum.p[ax_n.first] += ax_n.second;
   return sum;
 }
于 2013-03-15T13:42:29.877 回答
2

您的问题在于 sum(SIZE) 的构造

Polynomial Polynomial::operator+(const Polynomial& other)
{
         Polynomial sum(SIZE);

如果您这样做,并且第一个多项式的大小仅为 2,则稍后在该方法中您将复制到不属于您的内存中:

     if(other.SIZE > SIZE)
     {
        difference = other.SIZE - SIZE;

////这是您的问题 - 您的循环使用 other.SIZE,它大于 SIZE...

        for(int i = 0; i<other.SIZE; i++)
        {
             if(i - difference < 0)
                  sum.polyPtr[i] = other.polyPtr[i];

             else
             {
                 sum.polyPtr[i] = other.polyPtr[i] + 
                              polyPtr[i - difference];  
             }                            
        }         
     }

发生错误是因为您使用sum.polyPtr[i],当 SIZE < other.SIZE 发生时,它不存在。

于 2013-03-15T13:31:08.333 回答
1

你的代码太复杂了。这样的事情做得很好:

#include <algorithm>
#include <iostream>
#include <vector>
#include <iterator>
#include <sstream>

// helper to read the input polynomials into a output-iterator
template<class OutIter>
void read_vector(std::istream& is, OutIter first)
{
        // helper type to iterate over the input coefficients
        typedef std::istream_iterator<
                typename OutIter::container_type::value_type> iter_t;
        // buffer to hold the input line
        std::string buffer;
        // read it
        std::getline(is, buffer);
        // create a string stream with which we tokenize the input
        std::istringstream iss(buffer);
        // read coefficients into output container
        std::copy(iter_t(iss), iter_t(), first);
}

int main()
{
        std::vector<double> p1, p2;

        // read input
        std::cout << "Enter coefficients of the first polynomial: ";
        read_vector(std::cin, std::back_inserter(p1));
        std::cout << "Enter coefficients of the second polynomial: ";
        read_vector(std::cin, std::back_inserter(p2));

        // check for errors
        if (p1.empty() || p2.empty())
        {
            std::cerr << "Error: polynomials must not be empty\n";
            return 1;
        }

        // initialize result polynomial to 0. coefficients
        std::vector<double> p3(std::max(p1.size(), p2.size()), 0.);
        // copy first polynomial to the result, starting from the back
        std::copy(p1.rbegin(), p1.rend(), p3.rbegin());
        // add second polynomial, starting from the back
        std::transform(p2.rbegin(), p2.rend(), p3.rbegin(), p3.rbegin(),
                       std::plus<double>());

        // print result
        std::cout << "Sum: ";
        const size_t n = p3.size()-1;
        for (size_t i=0; i < n; ++i)
        {
                std::cout << std::showpos << p3[i] << "x^" << n-i;
        }
        std::cout << std::showpos << p3[n] << "\n";
}
于 2013-03-15T14:27:25.693 回答