C++ 减去对象的二阶std::vector

C++ 减去对象的二阶std::vector,c++,c++11,vector,C++,C++11,Vector,我有两个物体向量。比如: std::vector<thing> all_things; std::vector<thing> bad_things; 如果你不能命令他们,你可以使用暴力的方式。比较一下向量。例如: std::vector<Thing> all; std::vector<Thing> bad; std::vector<Thing> good (all.size()); auto it = std::copy_if (al

我有两个物体向量。比如:

std::vector<thing> all_things;
std::vector<thing> bad_things;

如果你不能命令他们,你可以使用暴力的方式。比较一下向量。例如:

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));
std::vector all;
std::病媒不良;
std::vector 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();});
resize(std::distance(all.begin(),it));

如果构建/复制
东西的成本很高,而且它的容器很长,而且坏消息太多,那么构建一个相同的长“不坏”数组不是一个好主意。实际上,所有.size()x good.size()的标志矩阵都必须基于
比较来填充。如果确保了唯一性,则可以避免通过BAD进行迭代。但是O(N2)是复杂度。

我建议使用类似于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;
}
std::vector减法(const std::vector&a,const std::vector&b){
std::向量子;
次级储备(a.规模());
用于(常数自动和项目:a){
if(std::find(b.begin(),b.end(),item)=b.end()){
sub.push_back(a);
}
}
返回子节点;
}

这是你想要实现的残酷版本。但如果你不能对向量的元素进行排序,这是你能做的最好的了。但是请记住,您需要能够比较
类型的两个对象,这意味着您需要提供
运算符==

从注释中,您的
对象可以排序,但没有意义

没关系

毫无意义地对它们进行排序

编写一个函数,取两个
对象
s,并给它们一个无意义的一致顺序,如果两个对象相等,则两个对象之间的比较不少于彼此

称之为
bool arb\u order\u thing(thing const&,thing const&)

现在
std::sort
两个向量并使用
std::set_difference

现在,如果复制成本很高,那么复制成本可能会很高。因此,相反,创建两个
thing const*
向量,编写
bool arb_order_thing_ptr(thing const*,thing const*)
(使用无意义的顺序进行解引用和比较),使用该顺序对指针向量排序,使用该顺序使用set_difference,然后转换回
向量


可选地,考虑编写一个<代码>事物const */COD> HASHER(不是一个代码> STD::hash < /COD>,因为它是全局的和粗鲁的),并且使用<代码> unOrdEdEdTys s手动完成这项工作。散列两个向量中较小的一个,然后根据另一个向量上的散列进行

std::copy\u测试。

向量中的元素是唯一的吗?@PaoloM需要排序(OP声明这是不可能的),因此,如果元素是唯一的,那么他应该使用a
thing
是否有合适的
运算符==
或等效值?我很难想象不能有顺序的东西。如果所有其他操作都失败,请将
memcmp
std::sort
一起使用,然后执行线性擦除。那么,为什么不按位图的RGB值对
对象进行排序呢?为什么要调整
所有
的大小?为什么将条目保留在子范围[
it
good.end()中
)部分形成?+1另外,对std::vector使用蛮力而不是使用其他容器也不必感到难过。根据您的情况,这可能是最快的方法,因为vector将其值放置在一个连续的分配中。最后一行似乎不起作用。为什么默认为const在<代码>好的<代码>中构造这么多<代码>的东西<代码>是无用的,是可以避免的?@NickyC:因为这是一个可怕的例子。你可以只使用一个反向插入器,不调整大小。这高度取决于用例。所以对于这个问题,你怎么做是毫无意义的。改进?也许不是,但它不会不必要地触发
所有的.size()
默认构造函数。
类型的默认构造函数甚至不必存在。调用
reserve
比触发重新分配更好。
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));
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;
}