如何制作随机 4x4 array<array<int,4>,4>
?这个 2D 数组的每个元素都应该是从 到 的区间中的唯一数字,包括从0
到15
。
例子:
6 7 5 4
10 11 12 15
1 3 2 8
9 14 0 13
以下是您可以遵循的一些步骤:
std::array<std::array<int, 4>, 4> myArray;
16
,其中包含从0
到的值15
。不是一个坏问题。这将是我的选择:
std::vector
我扩展了我的答案以包括仅使用和std::vector + std::array
(如 OP 所要求的)的问题的另一个(简单)解决方案。
#include <vector>
#include <array>
#include <algorithm>
using namespace std;
// ...
const int N = 4; // we want to have 4x4 arrays for now
// ...
// C++ was tremendously simplified over the years in order to
// get a much more complicated language. This is what you can do ...
// ...
// First, generate a std::vector of shuffled numbers [0..15] over 16 elements
vector<int> v;
for(int i=0; i<N*N; i++) v.push_back(v.size()); // initialize w/index
random_shuffle (v.begin(), v.end()); // shuffle element values
// (Variant 1) std::array (C++11), row-wise copy of the vector data
// + will only work with newer (C++11 enabled) compiler versions
array<array<int,N>,N> amat; // there's no assign() member, so we have
for(int i=0; i<N; i++) // to copy each row through external template
copy( v.begin()+i*N, v.begin()+(i+1)*N, amat[i].begin() );
// done
// ...
在 for 循环中,我们只进行了 4 次迭代,但总共有 4x4 个元素。因为 4 个矩阵行中的每一个都是 4 个元素宽,所以我们必须找到一种方法,如何从 shuffeld 16 元素一维向量 v: 中为每个矩阵行获取正确v.begin()+i*N ... v.begin()+(i+1)*N
的 4 个元素。如果i
为 0(第一次迭代),我们从 复制四个元素v[0 * N] ... v[0+1 * N]
,这意味着v[0] .. v[4]
。
这是一个序列,其中最后一个元素 v[4]不包含在副本中。这在某种程度上也是 C/C++ 中的一种惯用模式,类似于:for(i=START; i < END; i++) ...
. 因此 END 元素超出范围,不包括在内。
在第二次迭代(i = 1)中,我们有v[1 * N] ... v[1+1 * N]
,即v[4] ... v[8]
。你看到图案了吗?
// ...
// (Variant 2) std::vector (STL), row-wise copy of the vector data
// + should work with almost every c++ compiler
vector<vector<int>> vmat(N);
for(int i=0; i<N; i++)
vmat[i].assign( v.begin()+i*N, v.begin()+(i+1)*N );
// done
// ...
// TODO: now try to print all elements line 4x4 matrix
为什么打乱的顺序总是一样的?C 库使用随机数实现,它从相同的种子数开始生成始终相同的序列(这可能对调试很重要)。为了获得不同的改组,您必须在程序启动一次时重新初始化随机数生成器。
...
srand((unsigned)time(NULL))
...
为此,您需要 C-library time-header (for time()
) 和最有可能的 stdlib-header (for srand()
):
...
#include <ctime>
#include <cstdlib>
...
我故意尝试只提供非常简单的解决方案。因此,似乎没有生成器或 C++11 lambda 适合此目的。
问候
rbo