带有常数和的随机唯一元素的c ++向量

时间:2017-05-31 15:06:20

标签: c++ vector random

我有一个固定大小为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;
}

2 个答案:

答案 0 :(得分:0)

好的,有三个要求:

  • Sum应该修复
  • 非重复数字
  • 数字应在
  • 范围内

对于要求#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