2016-12-06 152 views
0

我創建了一個名稱空間,並在該名稱空間內創建了一個類。該類稱爲多項式。我創建了公共成員操作符來執行多項式對象之間的算術運算。然而,當我嘗試在主要使用它們時,他們不提供正確的輸出。成員操作員不工作

我不確定如果我的錯誤是在定義或使用它們的方式。

這裏是我正在處理的文件的一部分:

header | polynomial.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 | polynomial.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}。

我計劃使用的運營商主要如下:

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變成空。

+4

這將是更好,如果你可以發佈[MCVE。 –

+3

您是否驗證過每個步驟的輸入和輸出?即setCoeff設置是否正確等? –

回答

0

正如在評論中提到,沒有一個完整的例子是很難確定哪裏是失敗的,因爲我們不知道究竟是做方法: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(這很好),但是用於獲取多項式乘法的循環邏輯是錯誤的,從而獲取矢量中不存在的元素(例如,看看i=2j=0: 。

除此之外,你可以使用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