C++でユーザー定義サイズの2次元ベクトル(2D vector)を扱う方法
C++において、vectorの中にvectorを格納したものは「2次元ベクトル(2D vector)」と呼ばれます。これはいわゆる二次元配列のような使い方ができるデータ構造で、各行の要素数が異なる「ジャグ配列(ギザギザ配列)」としても扱えるのが特徴です。
アルゴリズム
Begin
2D vector型の変数 v を宣言する。
ベクター v に値を初期化する。
「the 2D vector is:」と出力する。
for (int i = 0; i < v.size(); i++)
for (int j = 0; j < v[i].size(); j++)
2D vector の値 v[i][j] を出力する。
End.サンプルコード
以下の例では、初期化子リストを使って2次元ベクトルを宣言し、値を設定しています。ネストしたforループで外側のループが行(v.size())、内側のループが列(v[i].size())を走査し、すべての要素を出力します。
#include <iostream>
#include <vector> // C++で2D vectorを使うためのヘッダーファイル
using namespace std;
int main() {
vector<vector<int> > v{ { 4, 5, 3, 10 }, // 値を指定して2D vectorを初期化
{ 2, 7, 11 },
{ 3, 2, 1, 12 } };
cout<<"the 2D vector is:"<<endl;
for (int i = 0; i < v.size(); i++) { // 2D vectorの出力
for (int j = 0; j < v[i].size(); j++)
cout << v[i][j] << " ";
cout << endl;
}
return 0;
}実行結果
the 2D vector is: 4 5 3 10 2 7 11 3 2 1 12
補足:サイズを指定して宣言する方法
初期値ではなく、あらかじめ決めた行数・列数で2次元ベクトルを作成したい場合は、以下のようにコンストラクタ引数でサイズを指定できます。
int rows = 3, cols = 4; vector<vector<int>> v(rows, vector<int>(cols)); // 3行4列の2D vector(すべて0で初期化) v[1][2] = 100; // 要素へのアクセスも通常の配列と同じように可能
このようにvector<vector<int>>を使えば、実行時にサイズを自由に決められる柔軟な二次元データ構造を実現できます。また、vectorは動的にメモリを管理するため、new/deleteによる手動のメモリ管理が不要になる点も大きなメリットです。
-
C++で解く「3nスライスのピザ」問題 ― 動的計画法でスライスの合計を最大化する方法
問題の概要 大きさがまちまちの 3n 個のスライスからなるピザがあるとします。私と友人2人は、次のルールに従ってピザを取っていきます。 私が任意のスライスを1枚選びます。 友人のAmalは、私が選んだスライスの反時計回り方向に隣接するスライスを取ります。 友人のBimalは、私が選んだスライスの時計回り方向に隣接するスライスを取ります。 ピザのスライスがなくなるまで、この手順を繰り返します。 各スライスの大きさは、時計回りの順に並べた環状配列 slices として与えられます。求めるのは、私が手にできるスライスの大きさの合計の最大値です。 入出力例 入力が [9, 8, 6, 1, 1,
-
C++でstd::vectorをシャッフルする方法(Fisher-Yatesアルゴリズム)
std::vectorの要素をシャッフルするには、古典的なFisher-Yatesシャッフルアルゴリズムを利用する方法があります。 このアルゴリズムでは、ベクターを先頭から線形に走査し、各要素を「その要素自身を含む残りの要素」の中からランダムに選ばれた要素と入れ替えていきます。これにより、すべての並び順が等しい確率で現れる、偏りのないシャッフルが実現できます。 アルゴリズム Begin show()関数を宣言する。 show()関数内で、ベクターのconst参照を引数として受け取る。 for (auto const& i : input) 変数iの値を