首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >成员运算符不工作

成员运算符不工作
EN

Stack Overflow用户
提问于 2016-12-06 13:19:53
回答 1查看 68关注 0票数 0

我创建了一个名称空间,并在该名称空间中创建了一个类。这个类叫做多项式。我创建了公共成员运算符来执行多项式对象之间的算术运算。然而,当我尝试在main中使用它们时,它们不能给出正确的输出。

我不确定我的错误是在定义上还是在使用它们的方式上。

以下是我正在处理的文件的一部分:

header |多项式.h

代码语言:javascript
复制
#ifndef _POLYNOMIAL_H_
#define _POLYNOMIAL_H_
//...
namespace algebra {
  class polynomial {
    std::vector<double> coeffStorage;
   public:
    //...
    double operator()(double x);
    polynomial operator+(polynomial p);
    polynomial& operator+=(polynomial p);
    polynomial operator-();
    polynomial operator-(polynomial p);
    polynomial& operator-=(polynomial p);
    polynomial operator*(polynomial p);
    polynomial& operator*=(polynomial p);
  };

polynomial operator+(double c, polynomial p);
polynomial operator*(double c, polynomial p);
//...
}

#endif

cpp | polynomial.cpp

代码语言:javascript
复制
//...
//evaluates the polynomial at x
double algebra::polynomial::operator()(double x) {
  double result = 0;

 for (int i = 0; i < size(); i++)
   result += std::pow(x, i) * getCoeff(i);

  return result;
}

algebra::polynomial algebra::polynomial::operator+(algebra::polynomial p) {
  algebra::polynomial result;

  result.resize(degree() + p.degree() + 1);

  for (int i = 0; i < result.size(); i++)
    result.setCoeff(i, (getCoeff(i) + p.getCoeff(i)));

  return result;
}

algebra::polynomial& algebra::polynomial::operator+=(algebra::polynomial p) {
  return ((*this) = (*this) + p);
}

algebra::polynomial algebra::polynomial::operator-() {
  algebra::polynomial result;

  for (int i = 0; i < size(); i++)
    result.setCoeff(i, -1 * getCoeff(i));

  return result;
}

algebra::polynomial algebra::polynomial::operator-(algebra::polynomial p) {
  return ((*this) + -p);
}

algebra::polynomial& algebra::polynomial::operator-=(algebra::polynomial p) {
  return ((*this) = (*this) - p);
}

algebra::polynomial algebra::polynomial::operator*(algebra::polynomial p) {
  algebra::polynomial result;
  double coeffSum = 0.0;

  result.resize(degree() + p.degree() + 1);

  for (int i = 0; i < result.size(); i++) {
    coeffSum = 0;
    for (int j = 0; j <= i; j++) {
      coeffSum = getCoeff(j) * p.getCoeff(i - j);
    }
    result.setCoeff(i, coeffSum);
  }
  return result;
}

algebra::polynomial& algebra::polynomial::operator*=(algebra::polynomial p) {
  return ((*this) = (*this) * p);
}

algebra::polynomial algebra::operator+(double c, polynomial p) {
  algebra::polynomial result = p;

  result.setCoeff(0, c + p.getCoeff(0));

  return result;
}

algebra::polynomial algebra::operator*(double c, polynomial p) {
  algebra::polynomial result = p;

  for (int i = 0; i < result.size(); i++)
    result.setCoeff(i, c * p.getCoeff(i));

  return result;
}
//...

多项式的系数存储在向量中。每个指标都属于多项式的次数。例如,2x^2 +3看起来像3*x^0 + 0*x^1 + 2*x^2,它在向量上存储为{3.0,0.0,2.0}。

我计划使用main中的运算符,如下所示:

代码语言:javascript
复制
algebra::polynomial p2;
  p2.setCoeff(0, 1);
  p2.setCoeff(1, 1);
  algebra::polynomial p3;
  p3.setCoeff(0, -1);
  p3.setCoeff(1, 1);

  algebra::polynomial px;
  px = p2 + p3;

  algebra::polynomial py;
  py = p3 * p2;

但是px和py结果是空的。

EN

回答 1

Stack Overflow用户

发布于 2016-12-10 11:07:59

正如评论中提到的,没有完整的示例很难确定哪里失败了,因为我们不知道到底是什么在做这些方法:degree()getCoeff(i)setCoeff(i, c)resize(sz),但我会尝试:

如果我假设:

在您的示例中,

  • degree()在两个多项式中都返回1,
  • resize(n)简单地调用std::vector::resize方法,
  • size()简单地调用std::vector::size method
  • getCoeff(i)setCoeff(i, c) get并更改i-esim向量元素;

则两个运算符(+和*)中的逻辑都是错误的:

  • In运算符+向量大小调整为3,循环获取两个输入向量的3个元素(但它们都只有2个元素!)。调整大小必须使用更大的次数+1。运算符*中的
  • 向量也调整为3(这很好),但用于进行多项式乘法的循环逻辑是错误的,得到的元素不存在于向量中(Ex.查看何时使用p.getCoeff(i-j) == p.getCoeff(2).

i=2j=0

除此之外,当你在自己的类中时,你可以使用std::vector::operator[]std::vector::resize来代替getCoeffsetCoeffresize方法(即使因为polynomial::resize应该是私有的,在类之外调整多项式的大小对我来说也是没有意义的)。

更正的方法是:

代码语言:javascript
复制
algebra::polynomial algebra::polynomial::operator+(algebra::polynomial p) {
    algebra::polynomial result;
    int maxDegree = std::max(p.degree(), degree());
    result.coeffStorage.resize(maxDegree + 1, 0.0);
    for (int i = 0; i <= maxDegree; i++) {
        double value = (i <= degree() ? coeffStorage[i] : 0)
                + (i <= p.degree() ? p.coeffStorage[i] : 0);
        result.coeffStorage[i] = value;
    }
    return result;
}

algebra::polynomial algebra::polynomial::operator*(algebra::polynomial p) {
    algebra::polynomial result;
    int resultDegree = degree() + p.degree();
    result.coeffStorage.resize(resultDegree + 1, 0.0);
    for (int i = 0; i <= degree(); i++) {
        for (int j = 0; j <= p.degree(); j++) {
            result.coeffStorage[i + j] += coeffStorage[i] * p.coeffStorage[j];
        }
    }
    return result;
}

现在,在多项式运算中,一些系数可能为零,如果幂更大的系数出现这种情况,次数就会减少,因此必须计算方法degree(),而不一定是size()-1。类似于:

代码语言:javascript
复制
int algebra::polynomial::degree() const {
    int d = std::max(0u, coeffStorage.size() - 1); 
    while(d > 0 && coeffStorage[d] == 0.0)
        d--;
    return d;
}

获取或设置系数的一种更短/更好的方法是使用operator[],而不是像这样使用getCoeffsetCoeff (如果您还添加了上限验证,可能会更好):

代码语言:javascript
复制
double &algebra::polynomial::operator[](size_t i) {
    if (i + 1 > coeffStorage.size())
        coeffStorage.resize(i + 1, 0.0);
    return coeffStorage[i];
}

最后,要打印结果,最好使用下面这样的方法打印出人类可读的结果:

代码语言:javascript
复制
std::string algebra::polynomial::str() const {
    std::stringstream ss;
    for (int d = degree(), i = d; i >= 0; i--) {
        double c = coeffStorage[i];
        if (c != 0) {
            if (!std::signbit(c) && i < d)
                ss << '+';
            if (i == 0 || c != 1.0)
                ss << c;
            if (i > 0)
                ss << "y"; // "x" can be confused with "*"?
            if (i > 1)
                ss << i;
        }
    }
    return ss.str();
}

这些方法允许我们进行如下测试:

代码语言:javascript
复制
int main() {
    algebra::polynomial pa, pb;
    // 4a² + 2a + 3
    pa[2] = 4; pa[1] = 2; pa[0] = 3;
    // 5a³ + 2
    pb[3] = 5; pb[0] = 2;
    std::cout << "pa = " << pa.str() << ", " << "pb = " << pb.str() << std::endl;
    std::cout << "pa + pb = " << (pa + pb).str() << std::endl;
    std::cout << "pa * pb = " << (pa * pb).str() << std::endl;

    return 0;
}

哪个控制台输出是:

代码语言:javascript
复制
pa = 4y2+2y+3, pb = 5y3+2
pa + pb = 5y3+4y2+2y+5
pa * pb = 20y5+10y4+15y3+8y2+4y+6
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40988337

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档