0

私は多項式クラスを書いている最中で、+ 演算子をオーバーロードしました。実際の過負荷プロセスに関して数日前に質問したところ、すばらしい回答がありました。ただし、私の質問は、私のプログラムの実際の機能に関するものです。

ユーザーが入力した 2 つの多項式を加算する必要があります。多項式を追加する場合、たとえ 2 つの多項式のサイズが異なっていても、同じ項のみを追加する必要があります。私のプログラムは、最初に入力された多項式が 2 番目よりも大きい場合は問題ありませんが、最初の多項式が 2 番目よりも小さい場合はエラーになります。より具体的には... 1つの用語を除外しているように見えることに気付きました。その上、2 つの類似項を一緒に追加してから、異なる指数で出力するようです。例: 2x^3 + 3x^3 = 5x^2。

参考までに、これはこのプログラムに関する私の以前の質問です:配列ポインターを含むクラスで + 演算子をオーバーロードする (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は、2 つの多項式sumの最大値である必要があります。SIZE

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 の係数を単純に保持しcoef[n]=aます。ここで、追加する必要がある要素を見つけるための試行錯誤を行います。

std::map<int,double> p;しかし、すべてを保存するために使用する方がはるかに簡単 です。p[n]=a;

デバッグと最適化を行わずに、単なるアイデア:

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

newそして、 any 、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;

////HERE IS YOUR PROBLEM - あなたのループは 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];  
             }                            
        }         
     }

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 に答える