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

如何从含重复元素的数组高效抽取M个不重复随机元素?

从含重复元素的数组中抽取M个唯一随机元素

需求

  • 抽取的元素必须唯一
  • 待抽样数组可能包含重复元素
  • 待抽样数组无需预先排序

原实现代码

#include <random>
#include <vector>
#include <algorithm>
#include <iostream>


const std::vector<int> sample(const std::vector<int>& input, size_t n) {
    std::random_device rd;
    std::mt19937 engine(rd());
    std::uniform_int_distribution<int> dist(0, input.size() - 1);
    
    std::vector<int> result;
    result.reserve(n);

    size_t id;
    do {
        id = dist(engine);
        if (std::find(result.begin(), result.end(), input[id]) == result.end())
            result.push_back(input[id]);
    } while (result.size() < n);

    return result;
}


int main() {
    std::vector<int> input{0, 0, 1, 1, 2, 2, 3, 3, 4, 4};

    std::vector<int> result = sample(input, 3);

    for (const auto& item : result)
        std::cout << item << ' ';
    std::cout << std::endl;
}

问题

上述算法效率较低,同时需要补充逻辑:判断数组中唯一元素数量是否不小于M,若不足则抽取所有唯一元素。

优化方案

通过std::unordered_set先对原数组去重,将去重后的集合转为vector,再用std::shuffle打乱顺序,最后根据唯一元素数量调整返回结果的大小:

const std::vector<int> sample(const std::vector<int>& input, size_t M) {
    std::unordered_set<int> rem_dups(input.begin(), input.end());
    if (rem_dups.size() < M) M = rem_dups.size();
    
    std::vector<int> result(rem_dups.begin(), rem_dups.end());
    std::mt19937 g(std::random_device{}());
    std::shuffle(result.begin(), result.end(), g);

    result.resize(M);
    return result;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 21:45:37