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

C++是否存在可将vector按9:1:1比例拆分为三个独立vector的函数?

C++ 按9:1:1比例拆分vector的实现方案

以下提供三种可直接落地的实现方案,可根据实际场景选择:

方案1:手动遍历实现(兼容性最高、逻辑直观)

不需要依赖STL算法,可自定义是否保留原vector的元素顺序,适合所有C++版本:

#include <vector>
template <typename T>
void split_vector(const std::vector<T>& src, std::vector<T>& out9, std::vector<T>& out1a, std::vector<T>& out1b) {
    const size_t total = src.size();
    // 按9:1:1计算各分组大小,余数默认归入最后一组,可根据需求调整取舍规则
    const size_t sz9 = total * 9 / 11;
    const size_t sz1 = total * 1 / 11;
    const size_t sz1b = total - sz9 - sz1;
    // 预分配空间避免扩容开销
    out9.reserve(sz9);
    out1a.reserve(sz1);
    out1b.reserve(sz1b);
    // 顺序拷贝元素,需要移动语义的话改为push_back(std::move(src[i]))
    for (size_t i = 0; i < sz9; ++i) {
        out9.push_back(src[i]);
    }
    for (size_t i = sz9; i < sz9 + sz1; ++i) {
        out1a.push_back(src[i]);
    }
    for (size_t i = sz9 + sz1; i < total; ++i) {
        out1b.push_back(src[i]);
    }
}

如果不需要保留原vector的内容,可将入参改为右值引用,配合std::move实现零拷贝拆分。

方案2:复用std::partition_copy实现

单次std::partition_copy仅支持拆分为2组,可通过两次调用实现3组拆分,适合不想手动写循环的场景:

#include <vector>
#include <algorithm>
#include <iterator>
template <typename T>
void split_vector(const std::vector<T>& src, std::vector<T>& out9, std::vector<T>& out1a, std::vector<T>& out1b) {
    const size_t total = src.size();
    const size_t sz9 = total * 9 / 11;
    const size_t sz1 = total * 1 / 11;
    // 第一次拆分:分出9份和剩余2份
    std::vector<T> temp;
    temp.reserve(total - sz9);
    out9.reserve(sz9);
    size_t idx = 0;
    std::partition_copy(src.begin(), src.end(),
        std::back_inserter(out9),
        std::back_inserter(temp),
        [&idx, sz9](const T&) { return idx++ < sz9; }
    );
    // 第二次拆分:把剩余2份拆为两个1份
    idx = 0;
    out1a.reserve(sz1);
    out1b.reserve(temp.size() - sz1);
    std::partition_copy(temp.begin(), temp.end(),
        std::back_inserter(out1a),
        std::back_inserter(out1b),
        [&idx, sz1](const T&) { return idx++ < sz1; }
    );
}

方案3:随机拆分(适用于训练/验证/测试集划分场景)

如果需要打乱原数据顺序再拆分,可先调用std::shuffle打乱数组后再用上述任意方法拆分:

#include <random>
#include <algorithm>
// 先打乱原数组,T替换为实际的元素类型
std::vector<T> shuffled_src = src;
std::shuffle(shuffled_src.begin(), shuffled_src.end(), std::mt19937{std::random_device{}()});
// 再调用上面的split_vector函数拆分shuffled_src即可

注意事项

  • 比例调整:如果原vector大小无法被11整除,可根据业务需求调整分组大小的计算规则,比如使用std::ceil向上取整第一组大小。
  • 性能优化:如果存储的是大对象,优先使用移动语义代替拷贝,可大幅降低内存开销。
  • C++20优化:使用C++20及以上版本时,可配合std::ranges::split_view先切分区间再拷贝,代码更简洁。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 20:54:04