(有效地)动态存储多项式

时间:2017-12-03 21:02:26

标签: c++ polynomials

我想要完成的是使用数组存储未知大小的多项式。 我在互联网上看到的是使用一个数组,每个单元格包含系数,度数是单元格数,但这不是有效的,因为如果我们有一个多项式,如:6x ^ 14 + x + 5。这意味着我们将在整个单元格中从1到13都有零。我已经看过一些带有向量和链表的解决方案但是有没有其他方法可以有效地解决这个问题,而不使用(std :: vectors或std) ::列表)?

2 个答案:

答案 0 :(得分:3)

除非有令人信服的理由采取其他行动(这是一项需要使用C风格数组的编程任务),否则应使用标准库中的std::vector。图书馆有一个原因:让你的生活更轻松。在您的计划环境中,开销可能微不足道。

您提到将多项式(例如4 * x ^ 5 + x - 1)存储在std::vector中且索引代表功率(例如[-1, 1, 0, 0, 0, 4])是低效的。这是事实,但除非你存储的度数大于1000的多项式,否则这种浪费是完全无关紧要的。对于"稀疏"多项式,高度但系数很少,你可以考虑使用一对矢量,每对的第一个值存储功率,第二个值存储系数。

答案 1 :(得分:0)

稀疏多项式可以用映射表示,其中零元素由不存在的键表示。以下是此类的示例:

#include <map>

//example of sparse integer polynomial
class SparsePolynomial{
    std::map<int,int> coeff;
    int& operator[](const int& degree);
    int get(int degree);
    void update(int degree, int val);
};

每当您尝试获取或更新元素的系数时,都会评估其在地图中的存在性。每次更新元素的系数时,都会检查该值是否为零。因此,地图的大小总是很小。

我们可以用operator[]替换这两种方法。但是,在这种情况下,我们将无法在更新操作期间检查零,因此存储将不如使用两个单独的方法进行访问和更新那样有效。

int SparsePolynomial::get(int degree){
    if (coeff.find(degree) == coeff.end()){
        return 0;
    }else{
        return coeff[degree];
    }
}

void SparsePolynomial::update(int degree, int val){
    if (val == 0){
        std::map<int,int>::iterator it = coeff.find(degree);
        if (it!=coeff.end()){
            coeff.erase(it);
        }
    }else{
        coeff[degree]=val;
    }
}

虽然这种方法为我们提供了更高效的存储,但它需要更多的时间来访问和更新,而不是矢量。然而,在稀疏多项式的情况下,差异可以很小。给定std::map大小N,元素的平均搜索复杂度为O(log N)。假设您有一个度为d的稀疏多项式和非零系数N。如果N远小于d,则访问和更新时间会足够小,不会引起注意。