根据一些标准拆分std :: vector

Hum*_*awi 1 c++ arrays vector c++11

我有一个包含一些数据的向量.我想根据一些标准将其拆分为常数的向量.例如:

using Point=std::pair<int,int>;
std::array<std::vector<Point>,4> split_to_4(const std::vector<Point>& data,std::function<size_t(Point)> criteria);
int main(){
    std::vector<Point> data;
    //fill data
    auto results=split_to_4(data,[](const Point& p){
        if(cond1) return 0;
        if(cond2) return 1;
        if(cond3) return 2;
        return 3;
    });
}
Run Code Online (Sandbox Code Playgroud)

实施的最佳方式是split_to_4什么?我目前的尝试是:

std::array<std::vector<Point>,4> split_to_4(const std::vector<Point>& data,std::function<size_t(Point)> criteria){
    std::array<std::vector<Point>,4> result;
    for (const auto& p : data){
        areas_regions[criteria(p)].emplace_back(p);
    }
    return result;
}
Run Code Online (Sandbox Code Playgroud)

任何更好的..更多的std方法呢?

通过Better,我的意思是:更具可读性......取决于迭代器......依赖于某些std函数......

Bau*_*gen 5

您可以通过多次调用来执行此操作std::partition:

// Returns iterators to the three partition points in the range
template<class ForwardIt, class Which>
auto split4(ForwardIt first, ForwardIt last, Which which) {
    std::array<ForwardIt, 3> ret;
    ret[0] = std::partition(first, last, 
                [&](const auto &v){return which(v) == 0;});
    ret[1] = std::partition(ret[0], last, 
                [&](const auto &v){return which(v) == 1;});
    ret[2] = std::partition(ret[1], last,
                [&](const auto &v){return which(v) == 2;});
    return ret;
}
Run Code Online (Sandbox Code Playgroud)

当然,which如果您愿意,您也可以直接传递和使用条件,而不是通过某些功能.

人们还可以通过循环重写这一点,以便splitN在必要时对其进行概括.(注意,这种方法的复杂性对于具有n个元素的范围是O(N*n).对于大N来说这可能是不合理的慢.另一方面,我们得到掉期而不是副本,这可能有帮助,如果复制很昂贵(与通话相比which).如果性能至关重要,请测量.)

如果您需要保留每个组中元素的相对顺序,那么std::stable_partition您的朋友.


刚刚注意到C++ 11标签:上面的代码是C++ 14.对于C++ 11兼容性,只需将auto我使用的s 更改为显式类型,即std::array<ForwardIt, 3>用作返回类型和const std::iterator_traits<ForwardIt>::value_type&lambdas.

为了简洁,我将保留原样,最后一段完成了前C++ 14人的答案.