我想创建一个 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, ]]
有不同的方法。您可以使用
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';
}
}