我有两个对象向量。类似的东西:
std::vector<thing> all_things;
std::vector<thing> bad_things;
我想获得包含 good_things 的第三个向量。换句话说, all_thing 中的每个对象都不属于 bad_things :
std::vector<thing> good_things=subtract(all_things,bad_things);
有关如何以最有效和最标准的方式实施减去的任何想法。
P.S矢量可以 NOT 被排序,因为类事物没有任何要排序的东西。 谢谢!
编辑:
我不想对all_things
做任何改动。
e.g。
void substract(const std::vector<thing>& a, const std::vector<thing>& b);
答案 0 :(得分:2)
从评论中,您的thing
可以按照无意义的方式进行排序。
没关系。
毫无意义地对它们进行排序。
编写一个函数,它接受两个thing
s并给它们一个无意义的顺序,如果它们是相等的,那么两个东西只能相互比较。
调用此bool arb_order_thing(thing const&, thing const&)
。
现在std::sort
两个向量并使用std::set_difference
。
现在,如果要复制的东西很昂贵,这可能会很昂贵。因此,创建两个thing const*
向量,写bool arb_order_thing_ptr(thing const*, thing const*)
(使用无意义排序进行解引用和比较),使用该向量对指针进行排序,使用set_difference,然后转换回{ {1}}。
或者,考虑编写vector<thing>
哈希(不是thing const*
,因为这是全局和粗鲁的)并使用std::hash<thing*>
来手动完成工作。散列两个向量中较小的一个,然后对另一个向量的散列进行unordered_set<thing const*>
测试。
答案 1 :(得分:1)
如果您无法订购,可以使用强力方式。只需比较矢量。 E.g:
std::vector<Thing> all;
std::vector<Thing> bad;
std::vector<Thing> good (all.size());
auto it = std::copy_if (all.begin(), all.end(), good.begin(),
[&bad](const Thing& t){return std::find(bad.begin(), bad.end(), t) == bad.end();} );
all.resize(std::distance(all.begin(),it));
答案 2 :(得分:1)
如果thing
构建/复制费用昂贵而且容器很长且坏处很多,那么构建同样长的“不坏”并不是一个好主意。阵列。实际上,必须根据thing
比较来填充all.size()x good.size()的标志矩阵。如果确保了单一性,那么可以避免迭代坏事。但O(N 2 )无论如何都是复杂的。
答案 3 :(得分:1)
我想建议类似于mkaes的代码,但几乎没有调整:
std::vector<thing> substract(const std::vector<thing>& a, const std::vector<thing>& b) {
std::vector<thing> sub;
sub.reserve(a.size());
for (const auto &item : a) {
if (std::find(b.begin(), b.end(), item) == b.end()) {
sub.push_back(a);
}
}
return sub;
}
这是你想要实现的残酷版本。但如果你不能对矢量元素进行排序,那么它是你能做的最好的。但请记住,您需要能够比较item
类型的两个对象,这意味着您需要提供operator==
。