You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何结合std::copy_if复制元素并从原容器移除已复制元素?

解决方案

你可以通过两种实用方式实现「移动偶数到新容器并从原容器移除」的需求,具体实现如下:

方法一:先移动元素,再用erase-remove_if清理原容器

基于你现有的代码,在完成元素移动后,直接用STL的erase-remove惯用法删除原容器中的偶数元素:

#include <vector>
#include <algorithm>

int main()
{
    std::vector<int> v = {1, 2, 3, 4, 5, 6};
    std::vector<int> even;
    
    // 移动偶数元素到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;});
    
    // 从v中移除所有偶数
    v.erase(std::remove_if(v.begin(), v.end(), 
                           [](int i){return i%2 == 0;}), 
            v.end());
    
    return 0;
}

注意:对于int这类简单类型,移动后原元素的值不会变化;如果是带资源的复杂类型(比如std::string),移动后的原元素处于有效但未定义状态,但remove_if的判断逻辑依然生效,因为只依赖值是否为偶数。

方法二:先分区再移动,减少遍历次数

这种方法先把原容器中的偶数元素移到容器末尾,再将这部分元素转移到even,最后截断原容器保留奇数元素。相比方法一,仅需两次遍历(分区+移动),效率更高:

#include <vector>
#include <algorithm>

int main()
{
    std::vector<int> v = {1, 2, 3, 4, 5, 6};
    std::vector<int> even;
    
    // 将偶数元素移动到容器末尾,返回第一个偶数元素的迭代器
    auto even_start = std::partition(v.begin(), v.end(), 
                                     [](int i){return i%2 != 0;});
    
    // 移动末尾的偶数元素到even
    even.insert(even.end(), 
                std::make_move_iterator(even_start), 
                std::make_move_iterator(v.end()));
    
    // 截断原容器,移除已移动的偶数元素
    v.erase(even_start, v.end());
    
    return 0;
}

如果需要保留原容器中奇数元素的相对顺序,可将std::partition替换为std::stable_partition,但后者时间复杂度会略高(O(n log n))。

内容的提问来源于stack exchange,提问作者ATK

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 06:55:14