我有一个固定大小为N = 5的std :: vector。我希望在两个正数之间随机选择向量的每个元素,特别是1和12.(不允许使用零)。每个元素都应该是在矢量上独一无二。
我该怎么做?到目前为止,实现允许元素为零并且在向量中具有重复。我想改进,以便不允许零和重复
到目前为止代码:
#include <algorithm>
#include <array>
#include <iostream>
#include <iterator>
#include <random>
int main() {
std::random_device rd;
std::mt19937 gen(rd());
constexpr int MAX = 20;
constexpr int LINES = 5;
int sum{};
int maxNum = 12;
int minNum = 1;
std::array<int, LINES> nums;
for (int i = 0; i < LINES; ++i) {
maxNum = std::min(maxNum, MAX - sum);
minNum = std::min(maxNum, std::max(minNum, MAX - maxNum * (LINES - i)));
std::cout << minNum << " " << maxNum << std::endl;
std::uniform_int_distribution<> dist(minNum, maxNum);
int num = dist(gen);
nums[i] = num;
sum += num;
}
std::shuffle(std::begin(nums), std::end(nums), gen);
std::copy(std::begin(nums), std::end(nums), std::ostream_iterator<int>(std::cout, " "));
std::cout << std::endl;
}
答案 0 :(得分:0)
好的,有三个要求:
对于要求#1,来自分布的更好的样本已经具有属性 - Dirichlet distribution。对于所有参数均等于1的最简单情况,它也称为单纯形采样,产生均匀分布在N
维单形上的数字。 HEre链接到C ++ code。
要满足第二和第三个要求,只需使用接受/拒绝
std::linear_congruential_engine<uint64_t, 2806196910506780709ULL, 1ULL, (1ULL<<63ULL)> ugen;
float MAX = 20.0f;
Simplex s(0.0f, 20.0f);
std::vector<float> v(5, 0.0f);
std::vector<int> r(5, 0);
for( ;; ) {
s.sample(v, ugen); // sampled Dirichlet
for(int k = 0; k != v.size(); ++k) {
r[k] = 1 + int(v[k]);
}
std::sort(r.begin(), r.end());
if (*r.rbegin() > 12) // array is sorted, just check last largest element
continue;
if (std::unique(r.begin(), r.end()) == r.end()) // no duplicates, good to go
break;
}
return r;
答案 1 :(得分:-2)
声明一个从false开始的布尔值,然后做一段时间,直到那个标志为真,迭代直到它们两者的总和= 5,你会检查总和是否为5 if语句,如果是,那么您将把标志的值更改为true。很简单。
我建议你多学习一点,因为你可能不熟悉编程(至少问题是我想到的问题,如果你不是,那么就会有明显的错误)。
另外,你去了:
If statements
While loop