简体   繁体   English

C ++多项式加法

[英]C++ Polynomial addition

I am trying to add two polynomials in C++ and I'm lost as to where to even start. 我试图在C ++中添加两个多项式,但我什至不知道从哪里开始。 So the user can enter values for a polynomial, they do not need to be in order or anything. 因此,用户可以输入多项式的值,而不必按顺序输入或输入任何值。

For example it can be: Poly 1: 2x^5 + 5x^2 - 2x + 9 Poly 2: x^2 + 0 例如,可以是:多边形1:2x ^ 5 + 5x ^ 2-2x + 9多边形2:x ^ 2 + 0

I have coefficient and exponent stored in the class (objects) private fields. 我将系数和指数存储在类(对象)专用字段中。 So would I look at the first exponent in Poly 1, search Poly 2 for same exponent first and if found add them? 那么,我会看看Poly 1中的第一个指数吗,首先在Poly 2中搜索相同的指数,如果找到,则添加它们? Then go on to the second term? 然后继续第二学期?

Code as requested: (NOTE: The implementation is currently wrong and I need help on how to work through this problem.) 要求的代码:(注意:目前的实现是错误的,我需要有关如何解决此问题的帮助。)

#include <cmath>
#include <iostream>
using namespace std;

class polynomial
{
public:
polynomial();
polynomial(int);
polynomial(int exponent[], int coefficient[], int);
~polynomial();
polynomial &operator = (const polynomial &obj);
int evaluate(double uservalue);
polynomial operator+(const polynomial &obj) const;
void operator-(const polynomial &obj) const;
void operator*(const polynomial &obj) const;
friend istream & operator>> (istream & in, polynomial &obj);
friend ostream & operator<< (ostream & out, const polynomial &obj);
friend void growone(polynomial &obj);
private:
int *coefficient;
int *exponent;
int size;
};

And the implementation 并执行

polynomial polynomial::operator+(const polynomial &obj) const
{
    bool matchFound = false;
    polynomial tmp;
    if (size >= obj.size) {
        for (int i = 0; i < size; i++) {
            if (i >= tmp.size) {
                growone(tmp);
            }
            for(int y = 0; i < obj.size; i++) {
                if (exponent[i] == obj.exponent[y]) {
                    tmp.coefficient[i] = (coefficient[i]+obj.coefficient[y]);
                    tmp.exponent[i] = exponent[i];
                    tmp.size++;
                    matchFound = true;
                }
            }
            if (matchFound == false) {
                tmp.coefficient[i] = coefficient[i];
                tmp.exponent[i] = exponent[i];
                tmp.size++;
            }
            matchFound = false;
        }
    } else {



    }
    return tmp;
}

You're not really using the power of C++ to its fullest there. 您并没有真正充分利用C ++的功能。 A good rule is that, if you are using non-smart pointers for anything, you should step back and have a rethink. 一个好的规则是,如果对任何东西都使用非智能指针,则应该退后一步,重新思考一下。

It's no accident that a large number of questions about C on Stack Overflow have to do about problems with pointers :-) 大量有关堆栈溢出C的问题与指针问题无关:-)并非偶然

The other point I would add is that it may be worth actually wasting a small amount of memory to greatly simplify your code. 我要补充的另一点是,实际上值得浪费少量的内存来大大简化代码。 By that, I mean don't try to create sparse arrays to hold your terms (coefficient-exponent pairs). 这样,我的意思是不要尝试创建稀疏数组来保存您的项(系数-指数对)。 Instead, allow each expression to hold every term up to its maximum, with the coefficients for the unused ones simply set to zero. 取而代之的是,让每个表达式最多保留每一项,并将未使用的项的系数简单地设置为零。 Unless you have an expression like 4x 99999999999999 + 3 , the amount of extra memory taken may be worth it. 除非您有类似4x 99999999999999 + 3的表达式,否则占用的额外内存量可能是值得的。

To that end, I'd propose using a std::vector for just the coefficients starting at an exponent of zero. 为此,我建议仅对从零指数开始的系数使用std::vector The exponents are actually decided by the position within the vector. 指数实际上是由向量中的位置决定的。 So the expression 4x 9 - 17x 3 + 3 would be stored as the vector: 所以表达式4x 9 - 17x 3 + 3将被存储为矢量:

{3, 0, 0, -17, 0, 0, 0, 0, 0, 4}
 0 <------- exponent -------> 9

That actually makes the task of adding and subtracting polynomials incredibly easy since the coefficients are all nicely lined up. 实际上,由于系数都很好地排列在一起,因此使多项式相加和相减的任务非常容易。


So, with that in mind, let's introduce a cut-down class for showing how it's done: 因此,考虑到这一点,让我们介绍一个简化的类以显示其完成方式:

#include <iostream>
#include <vector>

using std::cout;
using std::vector;
using std::ostream;

class Polynomial {
public:
    Polynomial();
    Polynomial(size_t expon[], int coeff[], size_t sz);
    ~Polynomial();
    Polynomial &operator=(const Polynomial &poly);
    Polynomial operator+(const Polynomial &poly) const;
    friend ostream &operator<<(ostream &os, const Polynomial &poly);
private:
    std::vector<int> m_coeff;
};

The default constructor (and the destructor) are very simple, we just ensure that an initialised polynomial always has at least one term: 默认的构造函数(和析构函数)非常简单,我们只需确保初始化的多项式始终具有至少一项:

Polynomial::Polynomial() { m_coeff.push_back(0); }
Polynomial::~Polynomial() {}

The constructor-from-array is a little more complex because we want to, as early as possible, turn the user's "anything goes" format into something we can use easily: 数组构造函数稍微复杂一点,因为我们希望尽早将用户的“一切”格式转换为易于使用的格式:

Polynomial::Polynomial(size_t expon[], int coeff[], size_t sz) {
    // Work out largest exponent and size vector accordingly.

    auto maxExpon = 0;
    for (size_t i = 0; i < sz; ++i) {
        if (expon[i] > maxExpon) {
            maxExpon = expon[i];
        }
    }
    m_coeff.resize(maxExpon + 1, 0);

    // Fill in coefficients.

    for (size_t i = 0; i < sz; ++i) {
        m_coeff[expon[i]] = coeff[i];
    }
}

Now you'll see why we made the decision to not use sparse arrays and to place the zero exponent at the start of the vector. 现在,您将了解为什么我们决定不使用稀疏数组,并将零指数放在向量的开头。 Bothe operator= and operator+ are simple because they already know where all terms are: operator=operator+都很简单,因为它们已经知道所有术语在哪里:

Polynomial &Polynomial::operator=(const Polynomial &poly) {
    if (this != &poly) {
        m_coeff.clear();
        for (int coeff: poly.m_coeff) {
            m_coeff.push_back(coeff);
        }
    }
    return *this;
}

Polynomial Polynomial::operator+(const Polynomial &poly) const {
    // Create sum with required size.

    size_t thisSize = this->m_coeff.size();
    size_t polySize = poly.m_coeff.size();

    Polynomial sum;
    if (thisSize > polySize) {
        sum.m_coeff.resize(thisSize, 0);
    } else {
        sum.m_coeff.resize(polySize, 0);
    }

    // Do the actual sum (ignoring terms beyond each limit).

    for (size_t idx = 0; idx < sum.m_coeff.size(); ++idx) {
        if (idx < thisSize) sum.m_coeff[idx] += this->m_coeff[idx];
        if (idx < polySize) sum.m_coeff[idx] += poly.m_coeff[idx];
    }

    return sum;
}

Now we just need to complete this with an output function and a small test mainline: 现在,我们只需要使用输出功能和一条小的测试主线来完成此操作:

ostream &operator<< (ostream &os, const Polynomial &poly) {
    bool firstTerm = true;
    if (poly.m_coeff.size() == 1 && poly.m_coeff[0] == 0) {
        os << "0";
        return os;
    }

    for (size_t idx = poly.m_coeff.size(); idx > 0; --idx) {
        if (poly.m_coeff[idx - 1] != 0) {
            if (firstTerm) {
                os << poly.m_coeff[idx - 1];
            } else if (poly.m_coeff[idx - 1] == 1) {
                os << " + ";
                if (idx == 1) {
                    os << poly.m_coeff[idx - 1];
                }
            } else if (poly.m_coeff[idx - 1] == -1) {
                os << " - ";
            } else if (poly.m_coeff[idx - 1] < 0) {
                os << " - " << -poly.m_coeff[idx - 1];
            } else {
                os << " + " << poly.m_coeff[idx - 1];
            }
            if (idx > 1) {
                os << "x";
                if (idx > 2) {
                    os << "^" << idx - 1;
                }
            }
            firstTerm = false;
        }
    }
    return os;
}

int main() {
    int    c1[] = {1, 2, 3, 4, 5};
    size_t e1[] = {3, 1, 4, 0, 9};
    Polynomial p1(e1, c1, (size_t)5);
    cout << "Polynomial 1 is " << p1 << " (p1)\n";

    int    c2[] = {6, 7, 8};
    size_t e2[] = {3, 7, 9};
    Polynomial p2(e2, c2, (size_t)3);
    cout << "Polynomial 2 is " << p2 << " (p2)\n";

    Polynomial p3 = p1 + p2;
    cout << "Polynomial 3 is " << p3 << " (p3 = p1 = p2);
}

And the output, which I've slightly reformatted to show like terms, shows it in action: 我对输出进行了稍微重新格式化以显示类似的术语,并将其显示为实际操作:

Polynomial 1 is   5x^9 +        3x^4 +  x^3 + 2x + 4
Polynomial 2 is   8x^9 + 7x^7 +        6x^3
                 ===================================
Polynomial 3 is  13x^9 + 7x^7 + 3x^4 + 7x^3 + 2x + 4

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM