成员操作员不工作

member operators not working

本文关键字:工作 操作员 成员      更新时间:2023-10-16

我创建了一个命名空间,并在该命名空间中创建了一个类。 该类称为多项式。 我创建了公共成员运算符来执行多项式对象之间的算术运算。 但是,当我尝试在 Main 中使用它们时,它们没有给出正确的输出。

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

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

标题 | 多项式.h

#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 | 多项式.cpp

//...
//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 中使用运算符,如下所示:

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 结果是空的。

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

如果我假设:

  • degree()示例中的两个多项式中都返回 1
  • resize(n)只是调用std::vector::resize方法,
  • size()只需调用std::vector::size方法
  • getCoeff(i)setCoeff(i, c)获取和更改i-esim向量元素;

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

  • 在运算符 + 中,向量的大小调整为 3,循环得到两个输入向量的 3 个元素(但它们都只有 2 个元素!调整大小必须使用较大的次数 +1。
  • 在运算符 * 中,向量
  • 的大小也调整为 3(这很好),但获取多项式乘法的循环逻辑是错误的,获取向量中不存在的元素(例如,请参阅 Wheni=2j=0p.getCoeff(i-j) == p.getCoeff(2)

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

更正的方法有:

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。像这样:

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如下(如果您也添加上限验证,可能会更好):

double &algebra::polynomial::operator[](size_t i) {
if (i + 1 > coeffStorage.size())
coeffStorage.resize(i + 1, 0.0);
return coeffStorage[i];
}

最后,要打印结果,最好使用如下方法打印为人类可读:

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();
}

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

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;
}

哪个控制台输出是:

pa = 4y2+2y+3, pb = 5y3+2
pa + pb = 5y3+4y2+2y+5
pa * pb = 20y5+10y4+15y3+8y2+4y+6