目前,我计划从 vector 中删除所有在集合中找不到的项目。
例如:
#include <vector>
#include <set>
#include <string>
#include <iostream>
using namespace std;
int main() {
std::set<string> erase_if_not_found;
erase_if_not_found.insert("a");
erase_if_not_found.insert("b");
erase_if_not_found.insert("c");
std::vector<string> orders;
orders.push_back("a");
orders.push_back("A");
orders.push_back("A");
orders.push_back("b");
orders.push_back("c");
orders.push_back("D");
// Expect all "A" and "D" to be removed.
for (std::vector<std::string>::iterator itr = orders.begin(); itr != orders.end();) {
if (erase_if_not_found.find(*itr) == erase_if_not_found.end()) {
orders.erase(itr);
// Begin from start point again? Do we have a better way?
itr = orders.begin();
} else {
++itr;
}
}
for (std::vector<std::string>::iterator itr = orders.begin(); itr != orders.end(); ++itr) {
std::cout << *itr << std::endl;
}
getchar();
}
虽然上面的代码有效,但效率不高,因为我每次删除一个项目都是从 vector 的起点开始。
有没有更好的办法?
最佳答案
是的;您可以将 erase/remove 习语与自定义谓词一起使用:
template <typename SetT>
struct not_contained_in_set_impl
{
not_contained_in_set_impl(const SetT& s) : set_(s) { }
template <typename T>
bool operator()(const T& v)
{
return set_.find(v) == set_.end();
}
const SetT& set_;
};
template <typename SetT>
not_contained_in_set_impl<SetT> not_contained_in_set(const SetT& s)
{
return not_contained_in_set_impl<SetT>(s);
}
用作:
orders.erase(
std::remove_if(orders.begin(),
orders.end(),
not_contained_in_set(erase_if_not_found)),
orders.end());
[在我脑海中快速编译]
如果您愿意首先对范围进行排序,您还有其他可能表现更好的选项(例如,std::set_intersection
)。
关于c++ - 从 vector 中删除项目的有效方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4031270/