题目:
数组 V 有 n 个互不相同的元素,从 V 中等概率抽取一个元素,但是这个元素不能是 m(m 是 V 中某个元素),如何抽取?
思路:
抽取前 n-1 个元素,如果不幸抽到了m,就用第n个元素替换
一开始思考直接抽取,抽到m之后偏移一下。但是这个思路并不ok,因为被偏移到的元素实际概率是 2/n ,所以应该先保证抽取的概率为 1/(n-1)。
代码:
#include <algorithm>
#include <iostream>
#include <random>
#include <vector>
int getRandInt(int be, int en)
{
// 创建一个随机数生成器
std::mt19937 generator(std::random_device {}());
// 定义随机数的范围 [be, en]
std::uniform_int_distribution<int> distribution(be, en);
// 生成随机数
int random_number = distribution(generator);
return random_number;
}
int main()
{
int n = 10;
std::vector<int> V = { 1, 43, 2, 29, 5, 31, 69, 13, 62, 85 };
int m = V[getRandInt(0, 10)]; //获取一个m
// 创建一个随机数生成器
std::mt19937 generator(std::random_device {}());
// 使用shuffle随机打乱向量中的元素
std::shuffle(V.begin(), V.end(), generator);
// 抽取过程
int result = -1;
int idx = getRandInt(0, n - 1 - 1); // 因为是闭区间,所以获取前n-1个数字,随机的最大下标为 n-1-1
if (V[idx] == m) {
result = V[n - 1];
} else {
result = V[idx];
}
return 0;
}