重载 * 运算符以将两个多项式相乘

Overloading the * operator to multiply two polynomials

本文关键字:两个 多项式 运算符 重载      更新时间:2023-10-16

初学者在这里C++。我特别需要帮助来弄清楚我的重载 * 运算符出了什么问题,该运算符应该将我制作的 Poly 类的两个多项式相乘。我的其他重载运算符似乎工作正常。这是原始问题:

P(x) = 2x4 + 3x3 – 12x2 + x – 19 (4th order polynomial)
  or 
P(x) = 2x7 + 5x5 – 7x2 + x – 19 (7th order polynomial)
Where the coefficients for the first and second equations can be described by the following array of     integers
'Coeff1[  ] = {-19, 1, -12, 3, 2}'
'Coeff2[[ ] = {-19, 1, -7, 0, 0, 5, 0, 2}'
Design and code a polynomial class in C++ that has the following properties:
class Poly{
private:
int order;  //order of the polynomial
int *coeff; // pointer to array of coeff on the heap
        // size of coeff array predicated on (order + 1)
public:
Poly( );        //default constructor – order=0 & coeff[0] =1
Poly(int Order , int Default = 1) ;// creates  Nth order poly
                                                             // and inits all coeffs
Poly(int Order, int *Coeff);  //creates an Nth polynomial & inits 
 ~Poly( );      // destructor
   :::::::                     // copy constructor
//mutators  & accessors
void set( ){// Query user for coefficient values);
void set(int coeff[ ], int size);  // input coeffs via external coeff vector
int getOrder( )const;  // get order of polynomial
int * get( );         //returns pointer to coeff array
//overloaded operators
Poly operator+( const Poly &rhs);       // add two polynomials
Poly operator-( const Poly &rhs);       // subt two polynomials
Poly operator*( const int scale);       // scale a  polynomial
Poly operator*(const Poly &rhs);        // mult two polynomials
bool  operator==(const Poly &rhs);      // equality operator
const int & operator[ ](int I)const;       // return the Ith coefficient
int & operator[ ](int I);                   // return the Ith coefficient
int operator( )(int X);         // evaluate P(x) according 
Poly & operator=(const Poly & rhs);
friend ostream & operator<<(ostream & Out, const Poly &rhs);
//other member functions
};
Demonstrate the following operations for the following Polynomials:
P1(x) = 2x4 + 3x3 – 12x2 + x – 19 (4th order polynomial)
P2(x) = 2x7 + 7x5 – 6x2 + x – 19 (7th order polynomial)
//display the following results  for the polynomials defined above
o   P3 = P1 + P2;
o   P3 = P2 – P1;
o   P3 = P1*10;
o   P3 = 10*P1;
o   P3 = P1*P2;
o   bool flag  = (P1==P2);
o   P1[3] = P2[5];  // assign the 5th coefficient of P2 to 3rd coefficient of P1
o   int Z = P1(int  X = 5);   // evaluate  Polynomial for input X
 // suggest using Horner’s method

o   The displayed polynomial for P2 should be printed as follows
    2X^7 + 7X^5 – 6X^2 + 1X – 1

这是我到目前为止的代码:

#include <iostream>
#include <cmath>
using namespace std;
class Poly
{
private:
int order;
int *coeff;
public:
Poly();
Poly(int Order, int Default=1);
Poly(int Order, int *Coeff);
Poly(const Poly &copy);
~Poly();
void set();                             //ask the user for the coefficient values
void set(int *Coeff, int size);            //put the coefficient values in a external coeff vector
int getOrder() const;               //gets the order of the polynomial
int* get() const;                             //returns pointer to coeff array
Poly operator +(const Poly &rhs);
Poly operator -(const Poly &rhs);
Poly operator *(const int scale);
Poly operator *(const Poly &rhs);

bool operator ==(const Poly &rhs);
const int & operator [](int access) const;
int & operator [](int access);
int operator ()(int X);
Poly & operator =(const Poly &rhs);
friend ostream & operator <<(ostream &Out, const Poly &rhs);
};
 int main()  {
 int coeff1[] = {-19,1,-12,3,2};
 int coeff2[] = {-19,1,-7,0,0,5,0,2};
 Poly P1(4,coeff1);
 Poly P2(7, coeff2);
 Poly P3;
 cout << "P1: " << P1 << endl;
 cout << "P2: " << P2 << endl;
 P3 = P1 * P2;
 cout << "P1 * P2: " << P3 << endl;
 return 0;
}

Poly::Poly() : order(0)
{
coeff = new int[1];
coeff[0] = 1;
}
Poly::Poly(int Order, int Default) : order(Order)
{
coeff = new int[order+1];
for (int i = 0; i < order+1; i++){
    coeff[i] = Default;
}
}
Poly::Poly(int Order, int *Coeff) : order(Order), coeff(Coeff)
{
}
Poly::Poly(const Poly & copy)
{
order = copy.getOrder();
coeff = new int[order+1];
for (int i = 0; i < order+1; i++){
    coeff[i] = copy.get()[i];
}
}
Poly::~Poly()
{
//if(coeff){
//delete [] coeff;
//}
}
void Poly::set()
{
cout << "Enter your coefficients:n";
for (int i = 0; i < order+1; i++){
    cin >> coeff[i];
}
}
void Poly::set(int *Coeff, int size)
{
delete [] coeff;
coeff = new int[size];
order = size;
for (int i = 0; i < order+1; i++){
    coeff[i] = Coeff[i];
}
} 
int Poly::getOrder() const
{
return order;
}
int* Poly::get() const
{
return coeff;
}
Poly Poly::operator +(const Poly &rhs)
{
int length = max(order+1, rhs.getOrder()+1);
int *answer = new int[length];
for (int i = 0; i < length + 1; i++){
    answer[i] = coeff[i] + rhs.get()[i];
}
if (order > rhs.getOrder()){
    for (int i = order+1 - rhs.getOrder()+1 ; i < order+1; i++){
        answer[i] = coeff[i];
    }
}
else if (order < rhs.getOrder()){
    for (int i = rhs.getOrder()+1 - order+1; i < rhs.getOrder()+1; i++){
        answer[i] = rhs.get()[i];
    }
}
return Poly(length-1, answer);
}
Poly Poly::operator -(const Poly &rhs)
{
int length = max(order+1, rhs.getOrder()+1);
int *answer = new int[length];
for (int i = 0; i < order+1 && i < rhs.getOrder() + 1; i++){
    answer[i] = coeff[i] - rhs.get()[i];
}
if (order > rhs.getOrder()){
    for (int i = order+1-rhs.getOrder()+1; i < order+1; i++){
        answer[i] = coeff[i];
    }
}
else if (order < rhs.getOrder()){
    for (int i = rhs.getOrder()+1 - order+1; i < rhs.getOrder()+1; i++){
        answer[i] = 0 - rhs.get()[i];
    }
}
return Poly(length-1, answer);
}
Poly Poly::operator *(const int scale)
{
int *answer = new int[order+1];
for (int i = 0; i < order+1; i++){
    answer[i] = coeff[i] * scale;
}
return Poly(order, answer);
}
Poly Poly::operator *(const Poly &rhs)
{    
int *shorter = NULL;
int *longer  = NULL;
int s = 0;
int l = 0;
if(order < rhs.getOrder()){
    shorter = coeff;
    s       = order;
    longer  = rhs.coeff;
    l       = rhs.order;
} else {
    shorter = rhs.coeff;
    s       = rhs.order;
    longer  = coeff;
    l       = order;
}
Poly sum = Poly(l, longer) * shorter[0];
int *prod;
int nl;
for (int i = 1; i <= s; i++){
    nl = l + i;
    prod = new int[nl + 1];
    for(int j = 0; j < i; j++){
        prod[j] = 0;
    }
    for(int k = 0; k <= l; k++){
        prod[k+i] = shorter[i] * longer[k];
    }
    sum = sum + Poly(nl, prod);
}
return sum; 
}
bool Poly::operator ==(const Poly &rhs)
{
bool result;
if (order == rhs.order){
    result = true;
    for(int i = 0; i<order+1; i++){
        if (coeff[i] != rhs.get()[i]){
            result = false;
        }
    }
}else result = false;
return result;
}
const int& Poly::operator[](int access) const
{
return coeff[order + 1 - access];
}
int& Poly::operator [](int access)
{
return coeff[order + 1 - access];
}
int Poly::operator ()(int x)
{
int total = 0;
for(int i = 0; i < order + 1; i++){
    total += coeff[i] * pow(x, i);
}
return total;
}
Poly &Poly::operator =(const Poly &rhs)
{
order = rhs.getOrder();
coeff = rhs.get();
return *this;
}
ostream& operator <<(ostream & Out, const Poly &rhs)
{
Out << rhs.get()[rhs.getOrder()] << "x^" << rhs.getOrder();      //first
for (int i = rhs.getOrder()-1; i > 0; i--){
    if (rhs.get()[i] < 0 || rhs.get()[i] > 1) {
    if(rhs.get()[i] > 0){
    Out << " + ";
    }
    Out  << rhs.get()[i] << "x^" << i << " ";
    }else if (rhs.get()[i] == 1){
        Out << "+ x ";
    }else if (rhs.get()[i] == 1){
        Out << "- x";
    }
}
if (rhs.get()[rhs.getOrder() - rhs.getOrder()] > 0) {
    Out << " + " << rhs.get()[rhs.getOrder() - rhs.getOrder()];      //last
}else Out << rhs.get()[rhs.getOrder() - rhs.getOrder()];      //last

Out << endl;
return Out;
}

'

这是我目前的输出。我不断得到的答案是正确答案的一半,但我似乎无法得到前半部分。

P1: 2x^4 + 3x^3 -12x^2 + x -19
P2: 2x^7 + 5x^5 -7x^2 + x -19
P1 * P2: -114x^5 + 49x^4 -76x^3  + 362x^2 -38x^1  + 361

任何帮助,不胜感激。谢谢

首先,停止手动管理内存。 将ordercoeff替换为 std::vector<int> values; 。 这将size()捆绑用于order,并为您处理内存管理。

如果您还不知道如何使用std::vector,请学习:这比学习如何编写自己的Poly类要容易得多。

实施Poly * Poly的下一步是实施Poly& operator*=( Poly const& rhs );

最后一步是friend Poly operator*( Poly lhs, Poly const& rhs ) { return std::move(lhs*=rhs); }没有理由使用多行,它可以inline

这就剩下operator*=.

实现的第一步*=它,所以通过Poly& operator+=(Poly const&)再次实现operator+(Poly const&, Poly const&)。 由于添加很容易,我将留给您。

下一步是标量乘法。 实施Poly& operator*=(int),并从中friend Poly operator*(Poly lhs, int x) { return std::move( lhs*=x ); }friend Poly operator*(int x, Poly rhs) { return std::move( rhs*= x ); }。 这称为"标量乘法"。

一旦我们有了这些,*=就变得容易了。

  1. 存储我们初始值的副本。( Poly init = std::move(*this); (

  2. 创建返回值(空(。

  3. 对于右侧的每个系数,请执行retval += coeff * init;

  4. return *this = std::move(retval);

这是解决方案的草图。 为了真正解决这个问题,您需要在每个阶段实施测试。 因为我在其他操作方面实现了*=,所以测试每个操作以确保它们正常工作是拥有可调试*=的关键。 然后你测试*=,然后你测试*,然后你就完成了。

如果您在兼容的C++编译器中进行编译,则使用 std::vector 的一个好处是,默认的复制、移动、分配和移动-分配操作可以执行正确的操作,默认析构函数也是如此。 寻求使用专门的资源管理类来管理资源,并遵循零法则,您的痛苦就会减少。

请注意,上述*=并不比*容易写,但总的来说*=更容易,所以无论如何你都应该养成这个习惯。

最后,请注意,这分配的内存多于所需内存,并且不是最佳选择。 但是,很容易正确。 在实现上述内容后,您可以通过多种方式使其更优化。 您可以使用 karatsuba 乘法,您可以使用表达式模板来避免result += coeff * init;行上的中间乘法,您可以在 resultreserve适量的空间,或者您可以手动开始使用索引。

第一步应该是正确性,因为如果你有一个正确的算法,你至少可以使用它来测试你更优化(更棘手(的算法。

您的代码(用于多项式乘法(不包含注释,并且相当不透明且难以阅读/理解。所以,我拒绝编译它(心理上(,只能猜测,但似乎你不知道多项式的乘法是如何定义的,因为你的乘积多项式设置为有 order = min(order(A(, order(B(( + 1,而正确的是 order(A(+order(B(。

我建议,你

1 在开始编码之前,请确保您了解多项式乘法

2 用最少的指令和有用的注释(或者更好的是:有用的变量名称(编写清晰的代码

3 通过C++标准库管理内存(使用std::vector<>(

4 构建您的代码(编写polynomial& polynomial::operator+=(polynomial const&)然后将产品定义为独立的(可以是friend(

polynomial operator*(polynomial const&a,polynomial const&b)
{
  auto c=a;
  c*=b;
  return std::move(c);
}

尽管您可能希望改进此特定设计(避免重新分配,这是c*=b操作中上述代码中的必要条件(。

我认为:

sum = sum + Poly(length, prod);

应该是

sum = sum + Poly(length + i - 1, prod);

此外,i上的循环应停止在数组长度的最短coeff

下面是该函数的修改版本:

 Poly Poly::operator *(const Poly &rhs)
 {
   int *shorter = NULL;
   int *longer  = NULL;
   int s = 0;
   int l = 0;
   if(order < rhs.order){
     shorter = coeff;
     s       = order;
     longer  = rhs.coeff;
     l       = rhs.order;
   } else {
     shorter = rhs.coeff;
     s       = rhs.order;
     longer  = coeff;
     l       = order;
   }
   Poly sum = Poly(l, longer) * shorter[0];
   int *prod;
   int nl;
   for (int i = 1; i <= s; i++){
     nl = l + i;
     prod = new int[nl + 1];
     for(int j = 0; j < i; j++){
       prod[j] = 0;
     }
     for(int k = 0; k <= l; k++){
       prod[k+i] = shorter[i] * longer[k];
     }
     sum = sum + Poly(nl, prod);
   }
   return sum;
 }

请注意它如何基于order值而不是coeff数组长度(与我在此答案顶部指出的修复相反(。

如果它不适合你,那么你在你没有提供的代码中可能有其他错误,或者你的算法适用于数组长度,所以你可能必须调整任何一个才能让事情正常工作。

最后,正如在其他答案中所说,您应该使用标准库提供的工具,而不是手动处理数组分配。