c++ - 用随机数创建一个 vector

标签 c++ c++11 random

我将如何创建一个充满随机数的 vector ?

通常的代码是这样的:

std::mt19937 rng {std::random_device{}()};
std::uniform_int_distribution<int> dist {1, 52};

std::vector<int> vec(10);
std::generate(begin(vec), end(vec), [&]{return dist(rng);} );

然而,这意味着每个值都被触摸了两次:一次设置为零,然后设置为随机值 (even at O3)

那么如何尽可能高效地做到这一点呢?

最佳答案

您可以创建一个函数调用迭代器并将其传递给 vector 范围构造函数:

#include <boost/iterator/iterator_facade.hpp>
#include <iostream>
#include <vector>
#include <random>
#include <tuple>

template<class F, class Tag = std::input_iterator_tag>
class FunctionCallIterator
    : public boost::iterator_facade<
          FunctionCallIterator<F, Tag>,
          typename std::result_of<F()>::type,
          Tag,
          typename std::result_of<F()>::type
      >
{
    std::tuple<F, ptrdiff_t> m_; // Enable empty base class optimization for empty F.
    friend class boost::iterator_core_access;
    typename std::result_of<F()>::type dereference() const { return std::get<0>(m_)(); }
    bool equal(FunctionCallIterator const& b) const { return std::get<1>(m_) == std::get<1>(b.m_); }
    void increment() { ++std::get<1>(m_); }
    void decrement() { --std::get<1>(m_); }
    void advance(ptrdiff_t n) { std::get<1>(m_) += n; }
    ptrdiff_t distance_to(FunctionCallIterator const& b) const { return std::get<1>(b.m_) - std::get<1>(m_); }
public:
    FunctionCallIterator(F const& f, ptrdiff_t n) : m_(f, n) {}
};

int main() {
    std::mt19937 rng {std::random_device{}()};
    std::uniform_int_distribution<int> dist {1, 52};
    auto f = [&]{return dist(rng);};
    using RngIter = FunctionCallIterator<decltype(f), std::random_access_iterator_tag>;
    std::vector<int> vec(RngIter{f, 0}, RngIter{f, 10});
    for(auto v : vec)
        std::cout << v << '\n';
}

push_back/back_inserter 方法相比,此方法不检查当前 vector 大小与其容量的关系,也不增加每个元素的 vector 大小。

关于c++ - 用随机数创建一个 vector ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52332286/

相关文章:

c++ - Qt 5.3 连接 lambda

c - "Segmentation fault 11"for 循环崩溃

c++ - opengl 模板缓冲区未初始化为零?

c++ - 这与 ObjectWrap::Unwrap 的 Holder

c++11 - C++ STL;迭代包含STL容器的类?

c++ - 如何从 std::initializer_list 构建类似 std::array 的数据结构

mysql - 如何在 SQL 中设置随机值的下限

php - 如何生成一个随机但唯一的数字并在我的图像标签源中显示该数字

c++ - 将 std::find_if 与 std::string 一起使用

c++ - QIcon 未显示在 QPushButton 上