在 C++ 中,将 std::numeric_limits<double>::max() 用作特殊的 "flag" 是否安全?
In c++, is it safe to use std::numeric_limits<double>::max() as a special "flag"?
给定
std::vector<double> a;
std::vector<int> ind;
其中 ind
1 升序排列。
我想执行以下操作:
for (auto it=ind.rbegin();it!=ind.rend();it++) a.erase(a.begin() + *it);
我想到了这个:
for (auto it=ind.begin();it!=ind.end();it++)
a[*it] = std::numeric_limits<double>::max();
std::erase(std::remove(a.begin(),a.end(),std::numeric_limits<double>::max()),a.end());
这非常快,但是在这种情况下使用 std::numeric_limits::max() 作为标志感觉不对。
当然,感觉不应该在等式中发挥太多作用......显然比较 std::remove 中的双打是安全的,并且在工作应用程序中这个向量的实践中永远不会出现限制,所以应该没问题吧?
对此有什么想法吗?
1) 参考 。 – 阿尔夫
让我们看看你的 "baseline" 代码,你说你想做 "equivalent" 的:
std::vector<double> a;
std::vector<int> ind;
for (auto it = ind.rbegin(); it != ind.rend(); it++)
a.erase(a.begin() + *it);
我们从中收集到的是 ind
是 a
中应该删除的索引向量,并且它们按升序排序。这些索引必须从 a
中删除。我假设您的目标是在 space 和时间方面有效地做到这一点。
如果按照所需的最少操作数考虑,则必须移动 a
中的 many/most/all 个元素才能擦除 ind
中的元素].您不想 erase()
多次,因为这意味着不止一次移动某些元素。一个最佳解决方案(在一般情况下,不对 a
中的值提出特殊要求)如下所示:
size_t slow = 0; // where we are currently copying "to"
std::vector<int> inditer = ind.begin();
for (size_t fast = 0; fast != a.size(); ++fast) {
if (inditer != ind.end() && *inditer == fast) {
// "remove" this element by ignoring it
++inditer;
} else {
a[slow] = a[fast];
++slow;
}
}
a.resize(slow);
现在,您可能可以使用 STL 算法和自定义谓词(函子)重新表述它,它会记住它在 ind
中的 "current" 位置,但代码不会少很多,而且可能是更难理解。
给定
std::vector<double> a;
std::vector<int> ind;
其中 ind
1 升序排列。
我想执行以下操作:
for (auto it=ind.rbegin();it!=ind.rend();it++) a.erase(a.begin() + *it);
我想到了这个:
for (auto it=ind.begin();it!=ind.end();it++)
a[*it] = std::numeric_limits<double>::max();
std::erase(std::remove(a.begin(),a.end(),std::numeric_limits<double>::max()),a.end());
这非常快,但是在这种情况下使用 std::numeric_limits::max() 作为标志感觉不对。
当然,感觉不应该在等式中发挥太多作用......显然比较 std::remove 中的双打是安全的,并且在工作应用程序中这个向量的实践中永远不会出现限制,所以应该没问题吧?
对此有什么想法吗?
1) 参考
让我们看看你的 "baseline" 代码,你说你想做 "equivalent" 的:
std::vector<double> a;
std::vector<int> ind;
for (auto it = ind.rbegin(); it != ind.rend(); it++)
a.erase(a.begin() + *it);
我们从中收集到的是 ind
是 a
中应该删除的索引向量,并且它们按升序排序。这些索引必须从 a
中删除。我假设您的目标是在 space 和时间方面有效地做到这一点。
如果按照所需的最少操作数考虑,则必须移动 a
中的 many/most/all 个元素才能擦除 ind
中的元素].您不想 erase()
多次,因为这意味着不止一次移动某些元素。一个最佳解决方案(在一般情况下,不对 a
中的值提出特殊要求)如下所示:
size_t slow = 0; // where we are currently copying "to"
std::vector<int> inditer = ind.begin();
for (size_t fast = 0; fast != a.size(); ++fast) {
if (inditer != ind.end() && *inditer == fast) {
// "remove" this element by ignoring it
++inditer;
} else {
a[slow] = a[fast];
++slow;
}
}
a.resize(slow);
现在,您可能可以使用 STL 算法和自定义谓词(函子)重新表述它,它会记住它在 ind
中的 "current" 位置,但代码不会少很多,而且可能是更难理解。