2010-04-14 2 views
3

Я следующий полиномиальный класс Я работаю на:Почему моя операционная система не работает правильно?

#include <iostream> 

using namespace std; 

class Polynomial 
{ 
//define private member functions 
private: 
    int coef[100]; // array of coefficients 
    // coef[0] would hold all coefficients of x^0 
    // coef[1] would hold all x^1 
    // coef[n] = x^n ... 

    int deg;  // degree of polynomial (0 for the zero polynomial) 

//define public member functions 
public: 
    Polynomial::Polynomial() //default constructor 
    { 
     for (int i = 0; i < 100; i++) 
     { 
     coef[i] = 0; 
     } 
    } 
    void set (int a , int b) //setter function 
    { 
     //coef = new Polynomial[b+1]; 
     coef[b] = a; 
     deg = degree(); 
    } 

    int degree() 
    { 
     int d = 0; 
     for (int i = 0; i < 100; i++) 
     if (coef[i] != 0) d = i; 
     return d; 
    } 

    void print() 
    { 
     for (int i = 99; i >= 0; i--) { 
     if (coef[i] != 0) { 
      cout << coef[i] << "x^" << i << " "; 
     } 
     } 
    } 

    // use Horner's method to compute and return the polynomial evaluated at x 
    int evaluate (int x) 
    { 
     int p = 0; 
     for (int i = deg; i >= 0; i--) 
     p = coef[i] + (x * p); 
     return p; 
    } 

    // differentiate this polynomial and return it 
    Polynomial differentiate() 
    { 
     if (deg == 0) { 
     Polynomial t; 
     t.set (0, 0); 
     return t; 
     } 
     Polynomial deriv;// = new Polynomial (0, deg - 1); 
     deriv.deg = deg - 1; 
     for (int i = 0; i < deg; i++) 
     deriv.coef[i] = (i + 1) * coef[i + 1]; 
     return deriv; 
    } 

    Polynomial Polynomial::operator + (Polynomial b) 
    { 
     Polynomial a = *this; //a is the poly on the L.H.S 
     Polynomial c; 

     for (int i = 0; i <= a.deg; i++) c.coef[i] += a.coef[i]; 
     for (int i = 0; i <= b.deg; i++) c.coef[i] += b.coef[i]; 
     c.deg = c.degree(); 

     return c; 
    } 

    Polynomial Polynomial::operator += (Polynomial b) 
    { 
     Polynomial a = *this; //a is the poly on the L.H.S 
     Polynomial c; 

     for (int i = 0; i <= a.deg; i++) c.coef[i] += a.coef[i]; 
     for (int i = 0; i <= b.deg; i++) c.coef[i] += b.coef[i]; 
     c.deg = c.degree(); 

     for (int i = 0; i < 100; i++) a.coef[i] = c.coef[i]; 
     a.deg = a.degree(); 

     return a; 
    } 

    Polynomial Polynomial::operator -= (Polynomial b) 
    { 
     Polynomial a = *this; //a is the poly on the L.H.S 

     Polynomial c; 

     for (int i = 0; i <= a.deg; i++) c.coef[i] += a.coef[i]; 
     for (int i = 0; i <= b.deg; i++) c.coef[i] -= b.coef[i]; 
     c.deg = c.degree(); 


     for (int i = 0; i < 100; i++) a.coef[i] = c.coef[i]; 
     a.deg = a.degree(); 

     return a; 
    } 

    Polynomial Polynomial::operator *= (Polynomial b) 
    { 
     Polynomial a = *this; //a is the poly on the L.H.S 
     Polynomial c; 

     for (int i = 0; i <= a.deg; i++) 
     for (int j = 0; j <= b.deg; j++) 
      c.coef[i+j] += (a.coef[i] * b.coef[j]); 
     c.deg = c.degree(); 

     for (int i = 0; i < 100; i++) a.coef[i] = c.coef[i]; 
     a.deg = a.degree(); 

     return a; 
    } 

    Polynomial Polynomial::operator - (Polynomial b) 
    { 
     Polynomial a = *this; //a is the poly on the L.H.S 
     Polynomial c; 

     for (int i = 0; i <= a.deg; i++) c.coef[i] += a.coef[i]; 
     for (int i = 0; i <= b.deg; i++) c.coef[i] -= b.coef[i]; 
     c.deg = c.degree(); 


     return c; 
    } 

    Polynomial Polynomial::operator * (Polynomial b) 
    { 
     Polynomial a = *this; //a is the poly on the L.H.S 
     Polynomial c; 

     for (int i = 0; i <= a.deg; i++) 
     for (int j = 0; j <= b.deg; j++) 
      c.coef[i+j] += (a.coef[i] * b.coef[j]); 
     c.deg = c.degree(); 
     return c; 
    } 
}; 

int main() 
{ 
    Polynomial a, b, c, d; 
    a.set (7, 4); //7x^4 
    a.set (1, 2); //x^2 

    b.set (6, 3); //6x^3 
    b.set (-3, 2); //-3x^2 

    c = a - b; // (7x^4 + x^2) - (6x^3 - 3x^2) 
    a -= b; 

    c.print(); 
    cout << "\n"; 


    a.print(); 
    cout << "\n"; 


    c = a * b; // (7x^4 + x^2) * (6x^3 - 3x^2) 
    c.print(); 

    cout << "\n"; 

    d = c.differentiate().differentiate(); 
    d.print(); 

    cout << "\n"; 

    cout << c.evaluate (2); //substitue x with 2 

    cin.get(); 
} 

Теперь у меня есть «-» перегружен и она отлично работает:

Polynomial Polynomial::operator - (Polynomial b) 
    { 
     Polynomial a = *this; //a is the poly on the L.H.S 
     Polynomial c; 

     for (int i = 0; i <= a.deg; i++) c.coef[i] += a.coef[i]; 
     for (int i = 0; i <= b.deg; i++) c.coef[i] -= b.coef[i]; 
     c.deg = c.degree(); 

     return c; 
    } 

Однако, я с трудом с моим «- =» оператор:

Polynomial Polynomial::operator -= (Polynomial b) 
    { 
     Polynomial a = *this; //a is the poly on the L.H.S 

     Polynomial c; 

     for (int i = 0; i <= a.deg; i++) c.coef[i] += a.coef[i]; 
     for (int i = 0; i <= b.deg; i++) c.coef[i] -= b.coef[i]; 
     c.deg = c.degree(); 

     // overwrite value of 'a' with the newly computed 'c' before returning 'a' 
     for (int i = 0; i < 100; i++) a.coef[i] = c.coef[i]; 
     a.deg = a.degree(); 

     return a; 
    } 

Я просто слегка видоизмененный мой «-» метод оператора перезаписать значение в «а» и возврата «а», а просто использовать «C» многочлен как темп ,

Я поместил в некоторой отладке оператора печати, и я подтверждаю, что во время вычислений, как:

с = а - Ь;

и

а - = Ь;

рассчитывается с одинаковым значением.

Однако, когда я иду, чтобы напечатать их, их результаты разные:

полиномиальной а, б; a.set (7, 4); // 7x^4 a.set (1, 2); // x^2

b.set (6, 3); // 6x^3 b.set ( -3, 2); // - 3x^2

c = a - b; // (7x^4 + x^2) - (6x^3 - 3x^2) a - = b;

c.print(); cout < < "\ n";

a.print(); cout < < "\ n";

Результат:

7x^4 -6x^3 4x^2

7x^4 1x^2

Почему мой c = a - b и a -= b дает мне разные результаты когда я иду печатать их?

+1

Вы должны объявить свои бинарные математические операторы (включая оператор присваивания, как '- =') взять константный вход задания. Кроме того, вы должны объявить, что ваши операторы присваивания возвращают ссылку, и используйте 'return * this;'. Поэтому ваш оператор вычитания и назначения должен выглядеть так: 'Polynomial & Polynomial :: operator - = (const Polynomial & b)'. –

+0

Другая ошибка: ваш конструктор не устанавливает 'deg'. Возможно, вам стоит рассмотреть возможность использования 'vector ' для ваших коэффициентов, если только вы не использовали его раньше, и в этом случае это может быть немного. –

ответ

8

Polynomial::operator -= не изменяется this, это изменение копии this. Если вы измените Polynomial a= *this на Polynomial &a= *this, то есть сделайте ссылку вместо копии, она будет работать, так как теперь вы изменяете *this через a. Кроме того, возвращаемое значение operator <op>= обычно является ссылкой, а не значением.

+2

Кроме того, все аргументы должны быть «Полиномиальная константа &». – Potatoswatter

1

Итак, во-первых, вы, вероятно, захотите пройти const Polynomial& вместо Polynomial к своим функциям, так как последний создает копию, а первый передает постоянную ссылку.

Во-вторых, я считаю, это очень странно, что вы пишете:

 
Polynomial b = *this; 

Вместо того, чтобы писать b.coeff[i], вы можете просто написать coef[i], так как он решает this->coef[i]. Если вы абсолютно необходимо использовать какой-либо другой переменной b, хотя, то я предлагаю вам использовать следующее при чтении:

 
const Polynomial& b = *this; 

И использовать следующие при написании:

 
Polynomial& b = *this; 

Обратите внимание, что если вы используете Polynomial вместо Polynomial&, то ваша переменная b является копией и не идентична *this; следовательно, сделанные вами изменения не повлияют на *this, как и предполагалось.

Тем не менее, писать deg = //... яснее, чем a.deg = //..., где a представляет *this. Я настоятельно рекомендую вам отказаться от привычки создавать переменные, которые (пытаются) ссылаться на *this.

Последнее примечание, как указано в комментарии, операторы присваивания должны возвращать ссылку на тип. Итак, ваши operator=, operator+=, operator-= и т. Д. Должны вернуть Polynomial&. Причина этого заключается в том, чтобы обеспечить эффективную цепочку в задании присваивания. Например: a = b = c. Если бы вы вернули void, это не сработало бы вообще. С возвращением копии Polynomial, она будет работать, но она без неопытных построит копии. Использование ссылки в этом случае (то есть Polynomial&) предотвращает копирование.

1

Оператор -= должен изменять левое значение (и возвращать ссылку на *this, чтобы разрешить цепочки).

Кроме того, общие для реализации этих функций в терминах другого:

//random example 
X& operator+= (const X& other) 
{ 
    this->sth += other.sth; 
    return *this; 
} 

//free function in terms of the previous 
//more verbose than needed for exposition 
X operator+ (const X& lhv, const X& rhv) 
{ 
    X result(lhv); 
    result += rhv; 
    return result; 
} 

В действительности большинство операторов могут (и должны) быть реализованы с точки зрения других людей, и есть даже Boost.Operators синтезировать связанные операторы из существующие.

+1

И, конечно, вычитание - это просто добавление отрицания второго операнда. – JohnMcG

+0

Если ваш проф дает вам возможность использовать Boost ...^_- –

Смежные вопросы