从c++向量中删除一个已知的项子集
Removing a known subset of items from a c++ vector
给定:
struct Item { int id; ... };
std::vector<Item> items;
std::vector<int> idsToRemove;
编写执行删除(同时保留顺序(的代码的最有效/最干净的方法是什么?
使用remove_if
,这可能是:
items.erase(std::remove_if(items.begin(), items.end(),
[&](const Item& i) {
return std::find(idsToRemove.begin(), idsToRemove.end(), i.id)
!= idsToRemove.end();
}), items.end());
另一种方式可能是:
for (auto id : idsToRemove)
{
items.erase(std::remove(items.begin(), items.end(), id), items.end());
// or items.erase(std::find(items.begin(), items.end(), id));
// provided that we know id always exists in items
}
这两个都感觉不太好(它们看起来都O(N*M((,尽管第二个看起来比第一个整洁。有更好的方法吗?
(如果有帮助的话,虽然两个向量都没有排序,但已知idsToRemove
是ID的子集,其顺序与它们在items
中出现的顺序相同,并且两个数组都很小。如果有合适的算法,我可以使用Boost算法。(
由于已知idsToRemove
中的id在items
中,并且顺序相同,因此可以在items
中使用几个迭代器来跟踪当前比较元素、当前目的地,并遍历idsToRemove
和items
,比较这两个元素,移动要保留的元素。在该过程结束时,将items
的大小调整为新的较小大小。
我不认为这是对所述问题的真正答案(因为它移动了门柱(,但这是我在调查它时发现的,它可能对未来的搜索有用。
如果您没有从外部传入idsToRemove
,但无论如何都需要遍历items
来决定删除哪个,那么在O(N(中有一种相当好的方法:
#include <boost/range/algorithm_ext/erase.hpp>
boost::range::remove_erase_if(items, [&](const Item& item)
{
// do whatever else you want to item
// return true to erase the item, or
return false; // to keep it
});
在内部,它基于std::remove_if
,但它更整洁,类似于基于的范围。
我假设您的元素具有唯一的ID,因此,与其将要删除的元素存储在std::vector
中,不如将它们存储在std::unordered_set
中。
通过这种方式,std::remove_if
方式真的很干净:
struct Item {
int id;
};
// ...
std::vector<Item> items;
std::unordered_set<int> idsToRemove;
items.erase(
std::remove_if(std::begin(items), std::end(items), [&](Item const& it) {
return (idsToRemove.find(it.id) != std::end(idsToRemove));
}),
std::end(items));
复杂度(摊销(将为O(N)
,其中N
是向量中元素的数量。
相关文章:
- 给定一个向量,如何找到该向量的所有子集和的原始索引
- 检查数值类型是否是另一个数值类型的子集
- 将 std::variant 转换为另一个具有类型子集的 std::variant
- (也许是NP-Hard)求一个集合的子集总数,使得每个子集在与其所有元素相乘时的值都大于X
- C/C :提取一个枚举的子集以形成新的枚举
- C 从向量的子集返回一个随机值
- 给定一个正整数 N 作为输入,我如何找到数字子集中的乘积
- 如何检查字符串是否是另一个字符串的正确子集
- 确定一个向量是否是另一个向量的子集的有效方法
- 给出两个二进制数,将一个子集从一个复制到另一个
- 一个多索引,其中一个索引是整个集合的子集
- 向量,包含指向同一内存的另一个向量的部分子集
- 我可以将矩阵的子集传递到MKL中的另一个函数中吗
- 给定一个长度为n的数组,找到子集的数量,其中子集的XOR等于给定数量
- 选择一个垫子的子集并复制它们以在C++/Opencv中创建一个新垫子
- 优化检查一个比特向量是否是另一个的适当子集
- 线性算法找到最小子集和超过一个阈值
- 从一个集合生成所有可能的有序子集
- 在 Rcpp 中,为什么我不能将子集向量分配给另一个子集向量
- 如何编译c++文件的一个子集,使我不必编译其他文件MinGW