c++ 如何使用std::copy_if来复制元素并从原始容器中删除这些元素

yqkkidmi  于 2022-12-20  发布在  其他
关注(0)|答案(2)|浏览(253)

假设我有一个std::vector<int>,使用一个简单的操作来复制偶数元素:

#include <vector>

int main()
{
    std::vector<int> v = {1, 2, 3, 4, 5, 6};
    std::vector<int> even;
    std::copy_if(std::make_move_iterator(v.begin()), std::make_move_iterator(v.end()), std::back_inserter(even), [](int i){return i%2 == 0;});
        
    return 0;
}

我的问题是,如何将上述方法与任何其他方法相结合,以从复制到向量even的向量v中移除元素

pb3skfrl

pb3skfrl1#

我不建议在这里使用std::copy_if,而是使用std::stable_partition将偶数元素移动到v的末尾,使用向量构造函数将这部分复制到even,然后从v中删除复制的元素:

int main()
{
    std::vector<int> v = { 1, 2, 3, 4, 5, 6 };
    
    // actual logic
    auto pivot = std::stable_partition(v.begin(), v.end(), [](int x) { return (x % 2) != 0;  });
    std::vector<int> even(pivot, v.end());
    v.erase(pivot, v.end());

    // display results
    std::cout << "v:\n";
    for (auto x : v)
    {
        std::cout << x << '\n';
    }

    std::cout << "even:\n";
    for (auto x : even)
    {
        std::cout << x << '\n';
    }

    return 0;
}

对于复制开销很大的对象,您可能希望在创建even时使用std::move_iterator,如@MooningDucks回答中所建议的:

std::vector<int> even(std::move_iterator(pivot), std::move_iterator(v.end()));
wfauudbj

wfauudbj2#

我会改用std::remove_if,并让传递给remove_if的函数与另一个向量相加,这就得到了

std::vector<int> v = {1, 2, 3, 4, 5, 6};
std::vector<int> even;
v.erase(std::remove_if(v.begin(), v.end(), 
                       [&](auto val){ bool cond = (val % 2 == 0); 
                       if (cond) even.push_back(val); return cond; }), v.end());

相关问题