如何在 C++ 中将 1 放在零矩阵(或二维数组)中的随机位置[已关闭]

问题描述 投票:0回答:1

我想创建一个 9x9 矩阵,其中有 10 个,在 C/C++ 中随机填充。

例如,它应该看起来像这样:

array[[ 0, 1, 0, 0, 0, 1, 0, 0, 0, ]
      [ 0, 0, 0, 0, 0, 0, 0, 0, 0, ]
      [ 0, 1, 0, 0, 0, 0, 0, 0, 0, ]
      [ 0, 0, 0, 0, 0, 0, 0, 1, 0, ]
      [ 0, 1, 0, 0, 0, 1, 0, 0, 0, ]
      [ 0, 0, 0, 0, 0, 0, 0, 0, 0, ]
      [ 0, 0, 0, 0, 0, 0, 0, 0, 1, ]
      [ 0, 0, 1, 0, 0, 0, 0, 0, 0, ]
      [ 1, 0, 0, 0, 0, 1, 0, 0, 0, ]]
c++ matrix random
1个回答
2
投票

有不同的方法。您可以使用

1
填充数组中的前 10 个位置,然后调用
std::shuffle
将它们置于随机位置。您还可以创建一个可用职位列表,然后从该列表中随机选择 10 个。

前者的注释示例:

#include <algorithm>  // shuffle
#include <array>      // array
#include <iostream>   //
#include <random>     // mt19937

int main() {
    constexpr unsigned side_size = 9;
    // a seeded pseudo number generator
    std::mt19937 prng(std::random_device{}());

    std::array<std::array<int, side_size>, side_size> arr_to_fill;
    unsigned ones = 10;  // the number of 1's we want

    // create an array with all available positions number from 0-
    std::array<unsigned, side_size * side_size> positions{};

    // put 1's in the first `ones` positions:
    std::fill_n(positions.begin(), ones, 1);

    // shuffle the array so the 1's are put in random positions
    std::shuffle(positions.begin(), positions.end(), prng);   

    // fill the array:
    for (size_t idx = 0; idx < positions.size(); ++idx) {
        arr_to_fill[idx / side_size][idx % side_size] = positions[idx];
    }

    // print result:
    for (auto& inner : arr_to_fill) {
        for (auto v : inner) std::cout << ' ' << v;
        std::cout << '\n';
    }
}

演示

(请注意,将 2d 数组转换为普通的 1d 数组并用 1 填充并直接对其进行洗牌是很诱人的,但随后您就处于 未定义行为 领域)


后者的注释示例:

#include <array>    // array
#include <iostream> // 
#include <numeric>  // iota
#include <random>   // mt19937, uniform_int_distribution

int main() {
    constexpr unsigned side_size = 9;
    // a seeded pseudo number generator
    std::mt19937 prng(std::random_device{}());

    // all zeroes:
    std::array<std::array<int, side_size>, side_size> arr_to_fill{};
    unsigned ones = 10;  // the number of 1's we want

    // create an array with all available positions number from 0-
    std::array<unsigned, side_size * side_size> positions;
    std::iota(positions.begin(), positions.end(), 0);  // [0, side_size^2)

    for (unsigned i = 0; i < ones; ++i) {
        unsigned last = positions.size() - 1 - i;  // last unpicked pos
        // distribution of random numbers from 0 to last (inclusive)
        std::uniform_int_distribution dist(0u, last);

        unsigned idx = dist(prng);         // get random index ...
        unsigned pos = positions[idx];     // ... to pick a position
        positions[idx] = positions[last];  // copy last unpicked position

        // put a 1 in the chosen positions place:
        arr_to_fill[pos / side_size][pos % side_size] = 1;
    }
    // print result:
    for (auto& inner : arr_to_fill) {
        for (auto v : inner) std::cout << ' ' << v;
        std::cout << '\n';
    }
}

演示


如果您可以使用外部库,您还可以使用

boost::multi::array
来简化此操作。

alfC提供的示例:

#include <multi/array.hpp> // boost::multi::array

#include <algorithm>  // shuffle
#include <iostream>   //
#include <random>     // mt19937

int main() {
    std::mt19937 prng(std::random_device{}());

    // create a 9x9 array, initialized with 0's:
    boost::multi::array<int, 2> A({9, 9}, 0);

    // fill the first 10 elements:
    std::fill_n(A.elements().begin(), 10, 1);

    // shuffle the array so the 1's end up in random positions:
    std::shuffle(A.elements().begin(), A.elements().end(), prng);

    // print result:
    for (auto const& row : A) {
        for (auto const& v : row) {
            std::cout << ' ' << v;
        }
        std::cout << '\n';
    }
}

演示

© www.soinside.com 2019 - 2024. All rights reserved.