ランダムな 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
にしました。
#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 要素幅であるため、シャッフルされた 16 要素の 1D ベクトル v: から各行列の行の正しいv.begin()+i*N ... v.begin()+(i+1)*N
4 つの要素を取得する方法を見つける必要があります。が 0 (最初の反復) の場合i
、 から 4 つの要素をコピーします。v[0 * N] ... v[0+1 * N]
これは、 を意味しv[0] .. v[4]
ます。
これは、最後の要素 v[4] がコピーに含まれていないシーケンスです。これは、次のようなC/C++の慣用的なパターンfor(i=START; i < END; i++) ...
でもあります。したがって、END 要素は範囲外であり、含まれません。
2 番目の反復 (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 ライブラリのタイム ヘッダー ( の場合time()
) と、おそらく stdlib-header ( の場合srand()
) が必要です。
...
#include <ctime>
#include <cstdlib>
...
私は意図的に非常に単純なソリューションのみを提供しようとしました。したがって、この目的に適したジェネレーターや C++11 ラムダはありませんでした。
よろしく
rbo