(有效地)动态存储多项式
(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;
}
}
虽然这种方法为我们提供了更高效的存储,但它需要比向量更多的时间来访问和更新。然而,在稀疏多项式的情况下,差异可能很小。给定大小 N
的 std::map
,元素的平均搜索复杂度为 O(log N)
。假设您有一个稀疏多项式,其次数为 d
,非零系数的个数为 N
。如果 N
比 d
小得多,那么访问和更新时间将足够小,不会引起注意。
我想要完成的是使用数组存储未知大小的多项式。 我在互联网上看到的是使用一个数组,每个单元格都包含系数,度数是单元格编号,但这并不有效,因为如果我们有一个多项式,如: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;
}
}
虽然这种方法为我们提供了更高效的存储,但它需要比向量更多的时间来访问和更新。然而,在稀疏多项式的情况下,差异可能很小。给定大小 N
的 std::map
,元素的平均搜索复杂度为 O(log N)
。假设您有一个稀疏多项式,其次数为 d
,非零系数的个数为 N
。如果 N
比 d
小得多,那么访问和更新时间将足够小,不会引起注意。