C++で配列の中身を以下のように初期化したい場合があります。

#include <iostream>
#include <array>

using namespace std;

int main()
{
	array<int , 10> arr;

	//配列の値を「0,1,2,...,N」と初期化
	int i = 0;
	for(auto& val : arr)
	{
		val = i++;
	}

	for(const auto val : arr)
	{
		cout << val << endl;
	}

	return 0;
}

もちろん、この書き方でも問題ありませんが、便利な関数としてiota(※itoaじゃないです)というものが実装されました。

#include <iostream>
#include <array>
#include <numeric>

using namespace std;

int main()
{
	array<int , 10> arr;

	//配列の値を「0,1,2,...,N」と初期化
	iota(arr.begin(), arr.end(), 0);

	for(const auto val : arr)
	{
		cout << val << endl;
	}

	return 0;
}

引数はそれぞれ、
・第一引数 シーケンス先頭
・第二引数 シーケンス終端
・第三引数 初期化の最初の値
となっています。つまり、第三引数に渡した値を始めとして、そこから順番に「+1」していった値を配列に代入しています。
他の例として、以下のように文字のA~Zまでを順番に入れるということもできます。

#include <iostream>
#include <array>
#include <numeric>

using namespace std;

int main()
{
	array<char , 26> arr;

	//配列の値を「A,B,C,...,Z」と初期化
	iota(arr.begin(), arr.end(), 'A');

	for(const auto val : arr)
	{
		cout << val << endl;
	}

	return 0;
}

今回のように、「0,1,2,...,N」と値が入った配列はその値を長さNの配列の添字として利用することが出来ます。

次にshuffleについて説明します。さっきのiotaによって生成した「0,1,2,...,N」という値を配列の添字に使えると言いましたが、順番にではなく、ランダムな添字で配列にアクセスしたいうことがあります。そのような場合に使えるのがshuffle関数です。

#include <iostream>
#include <array>
#include <numeric>
#include <algorithm>
#include <random>

using namespace std;

int main()
{
	array<int , 10> arr;

	//配列の値を「0,1,2,...,N」と初期化
	iota(arr.begin(), arr.end(), 0);

	for(const auto val : arr)
	{
		cout << val << ' ';
	}
	cout << endl;

	//random_deviceによるランダムに並び替え
	shuffle(arr.begin(), arr.end(), random_device{});

	for(const auto val : arr)
	{
		cout << val << ' ';
	}
	cout << endl;

	return 0;
}

shuffle関数の引数は
・第一引数 シーケンス先頭
・第二引数 シーケンス終端
・第三引数 乱数生成の種類
となっています。第三引数は、C++11講座10回で説明した乱数生成の種類(mt19937等)を指定してあげればいいです。
※実は、前からrandom_shuffleという同様の機能の関数はあったが、乱数の生成が標準のrandを採用していたため精度が悪い問題がありました。(ちなみに、rand、srand、random_shuffleなどはC++14で非推奨になったらしいです。)


トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS