给定
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 中的 double 是安全的,并且在工作应用程序的这个 vector 中实践中永远不会出现限制,所以它应该没事吧?
对此有什么想法吗?
1) 引用 comment by the OP . – 阿尔夫
最佳答案
让我们看看你的“基线”代码,你说你想做以下的“等效”:
std::vector<double> a;
std::vector<int> ind;
for (auto it = ind.rbegin(); it != ind.rend(); it++)
a.erase(a.begin() + *it);
我们从这里收集到的是 ind
是 a
中应该删除的索引 vector ,并且它们按升序排序。这些索引必须从 a
中删除。我假设您的目标是在空间和时间方面高效地做到这一点。
如果您根据所需的最少操作数来考虑它,您必须移动 a
中的许多/大部分/所有元素才能删除 指示的元素找到
。您不想 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
中的“当前”位置,但是代码不会少很多,而且可能会更难理解。
关于c++ - 在 C++ 中,将 std::numeric_limits<double>::max() 用作特殊的 "flag"是否安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28548637/