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

(effectively) storing a polynomial dynamically

我想要完成的是使用数组存储未知大小的多项式。 我在互联网上看到的是使用一个数组,每个单元格都包含系数,度数是单元格编号,但这并不有效,因为如果我们有一个多项式,如:6x^14+x+5。这意味着我们将在从 1 到 13.Ive 的所有单元格中都有零或 std::list)?

除非有令人信服的理由不这样做(这是一项要求您使用 C 样式数组的编程任务),否则您应该使用标准库中的 std::vector。图书馆存在的原因是:让您的生活更轻松。在您的程序上下文中,开销可能微不足道。

您提到将多项式(例如 4*x^5 + x - 1)存储在 std::vector 中,索引表示幂(例如 [-1, 1, 0, 0, 0, 4])效率低下。这是事实,但除非您存储次数大于 1000 的多项式,否则这种浪费完全可以忽略不计。对于 "sparse" 多项式,次数高但系数很少,您可以考虑使用成对的向量,每对的第一个值存储功率,第二个值存储系数。

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

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

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