给出
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 )参考comment by the OP。 - Alf
答案 0 :(得分:3)
让我们来看看你的&#34;基线&#34;代码,你说你想做&#34;等价的&#34;的:
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
中删除这些索引。我认为你的目标是在空间和时间方面有效地做到这一点。
如果按照所需的最小操作次数来考虑,则必须移动a
中的许多/大部分/全部元素,以便删除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算法和自定义谓词(仿函数)重新构造它,它可以记住它的当前&#34; ind
中的位置,但代码不会少得多,也可能难以理解。