[C++] vectorで2次元配列を生成する方法をわかりやすく解説
C++で2次元配列を生成するには、std::vector
をネストして使用します。
具体的には、外側のvector
が行を、内側のvector
が列を表します。
例えば、std::vector<std::vector<int>> matrix(rows, std::vector<int>(cols, 初期値));
のように記述します。
ここでrows
は行数、cols
は列数、初期値
は各要素の初期値を指定します。
この方法により、動的なサイズ変更が可能な2次元配列を簡単に作成できます。
vectorで2次元配列を生成する基本的な方法
C++のvector
を使用して2次元配列を生成する方法は非常にシンプルです。
vector
は動的配列であり、サイズを変更できるため、2次元配列を扱うのに適しています。
以下に基本的な生成方法を示します。
1. vectorの初期化
まず、2次元配列を生成するために、vector
のベクトルを使用します。
以下のコードでは、3行4列の2次元配列を生成しています。
#include <iostream>
#include <vector>
int main() {
// 3行4列の2次元配列を生成
std::vector<std::vector<int>> array(3, std::vector<int>(4));
// 配列に値を代入
for (int i = 0; i < 3; ++i) {
for (int j = 0; j < 4; ++j) {
array[i][j] = i * j; // 行と列のインデックスの積を代入
}
}
// 配列の内容を表示
for (int i = 0; i < 3; ++i) {
for (int j = 0; j < 4; ++j) {
std::cout << array[i][j] << " "; // 各要素を表示
}
std::cout << std::endl; // 行の終わりで改行
}
return 0;
}
0 0 0 0
0 1 2 3
0 2 4 6
2. vectorのサイズ変更
vector
の特性を活かして、後からサイズを変更することも可能です。
以下のコードでは、最初に2行3列の配列を生成し、その後に行数を増やしています。
#include <iostream>
#include <vector>
int main() {
// 2行3列の2次元配列を生成
std::vector<std::vector<int>> array(2, std::vector<int>(3));
// 配列に値を代入
for (int i = 0; i < 2; ++i) {
for (int j = 0; j < 3; ++j) {
array[i][j] = i + j; // 行と列のインデックスの和を代入
}
}
// 行数を増やす
array.push_back(std::vector<int>(3, 0)); // 新しい行を追加
// 配列の内容を表示
for (int i = 0; i < array.size(); ++i) {
for (int j = 0; j < array[i].size(); ++j) {
std::cout << array[i][j] << " "; // 各要素を表示
}
std::cout << std::endl; // 行の終わりで改行
}
return 0;
}
0 1 2
1 2 3
0 0 0
このように、vector
を使うことで、簡単に2次元配列を生成し、操作することができます。
動的にサイズを変更できるため、柔軟なデータ構造として非常に便利です。
2次元配列の操作方法
C++のvector
を使用した2次元配列の操作は、基本的な配列と同様に行えますが、動的なサイズ変更や便利なメソッドを利用できる点が特徴です。
ここでは、2次元配列の基本的な操作方法について解説します。
1. 要素のアクセス
2次元配列の要素には、行と列のインデックスを使用してアクセスします。
以下のコードでは、特定の要素にアクセスし、その値を表示しています。
#include <iostream>
#include <vector>
int main() {
// 2行3列の2次元配列を生成
std::vector<std::vector<int>> array = {
{1, 2, 3},
{4, 5, 6}
};
// 特定の要素にアクセス
int value = array[1][2]; // 2行目3列目の要素を取得
std::cout << "2行目3列目の要素: " << value << std::endl; // 値を表示
return 0;
}
2行目3列目の要素: 6
2. 行の追加と削除
vector
を使用すると、行の追加や削除が簡単に行えます。
以下のコードでは、行を追加し、特定の行を削除する方法を示しています。
#include <iostream>
#include <vector>
int main() {
// 2行3列の2次元配列を生成
std::vector<std::vector<int>> array = {
{1, 2, 3},
{4, 5, 6}
};
// 新しい行を追加
array.push_back({7, 8, 9}); // 3行目を追加
// 1行目を削除
array.erase(array.begin()); // 1行目を削除
// 配列の内容を表示
for (const auto& row : array) {
for (const auto& elem : row) {
std::cout << elem << " "; // 各要素を表示
}
std::cout << std::endl; // 行の終わりで改行
}
return 0;
}
4 5 6
7 8 9
3. 行列の転置
行列の転置は、行と列を入れ替える操作です。
以下のコードでは、2次元配列の転置を行っています。
#include <iostream>
#include <vector>
int main() {
// 2行3列の2次元配列を生成
std::vector<std::vector<int>> array = {
{1, 2, 3},
{4, 5, 6}
};
// 転置行列を生成
std::vector<std::vector<int>> transposed(array[0].size(), std::vector<int>(array.size()));
for (int i = 0; i < array.size(); ++i) {
for (int j = 0; j < array[i].size(); ++j) {
transposed[j][i] = array[i][j]; // 行と列を入れ替え
}
}
// 転置行列の内容を表示
for (const auto& row : transposed) {
for (const auto& elem : row) {
std::cout << elem << " "; // 各要素を表示
}
std::cout << std::endl; // 行の終わりで改行
}
return 0;
}
1 4
2 5
3 6
4. 2次元配列の初期化
2次元配列を初期化する際に、特定の値で埋めることも可能です。
以下のコードでは、すべての要素を0で初期化しています。
#include <iostream>
#include <vector>
int main() {
// 3行4列の2次元配列を0で初期化
std::vector<std::vector<int>> array(3, std::vector<int>(4, 0)); // すべての要素を0で初期化
// 配列の内容を表示
for (const auto& row : array) {
for (const auto& elem : row) {
std::cout << elem << " "; // 各要素を表示
}
std::cout << std::endl; // 行の終わりで改行
}
return 0;
}
0 0 0 0
0 0 0 0
0 0 0 0
このように、vector
を使用した2次元配列の操作は非常に柔軟で、さまざまな方法でデータを管理できます。
応用的な使い方
C++のvector
を使用した2次元配列は、基本的な操作に加えて、さまざまな応用が可能です。
ここでは、いくつかの応用的な使い方を紹介します。
1. 2次元配列を使ったグリッドの表現
2次元配列は、ゲームやシミュレーションなどでグリッドを表現するのに便利です。
以下のコードでは、簡単な迷路を表現しています。
#include <iostream>
#include <vector>
int main() {
// 迷路を表現する2次元配列
std::vector<std::vector<char>> maze = {
{'#', '#', '#', '#', '#'},
{'#', ' ', ' ', '#', '#'},
{'#', '#', ' ', ' ', '#'},
{'#', ' ', '#', ' ', '#'},
{'#', '#', '#', '#', '#'}
};
// 迷路の内容を表示
for (const auto& row : maze) {
for (const auto& cell : row) {
std::cout << cell; // 各セルを表示
}
std::cout << std::endl; // 行の終わりで改行
}
return 0;
}
#####
# ##
## #
# # #
#####
2. 2次元配列を使った行列計算
行列の加算や乗算などの計算も、2次元配列を使って実装できます。
以下のコードでは、2つの行列の加算を行っています。
#include <iostream>
#include <vector>
int main() {
// 2つの2次元配列を定義
std::vector<std::vector<int>> matrixA = {
{1, 2, 3},
{4, 5, 6}
};
std::vector<std::vector<int>> matrixB = {
{7, 8, 9},
{10, 11, 12}
};
// 行列の加算
std::vector<std::vector<int>> result(matrixA.size(), std::vector<int>(matrixA[0].size()));
for (int i = 0; i < matrixA.size(); ++i) {
for (int j = 0; j < matrixA[i].size(); ++j) {
result[i][j] = matrixA[i][j] + matrixB[i][j]; // 各要素を加算
}
}
// 結果の行列を表示
for (const auto& row : result) {
for (const auto& elem : row) {
std::cout << elem << " "; // 各要素を表示
}
std::cout << std::endl; // 行の終わりで改行
}
return 0;
}
8 10 12
14 16 18
3. 2次元配列を使ったデータの集計
2次元配列を使用して、データの集計や統計処理を行うこともできます。
以下のコードでは、各行の合計を計算しています。
#include <iostream>
#include <vector>
int main() {
// 2次元配列を定義
std::vector<std::vector<int>> data = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
// 各行の合計を計算
for (int i = 0; i < data.size(); ++i) {
int sum = 0;
for (int j = 0; j < data[i].size(); ++j) {
sum += data[i][j]; // 各要素を加算
}
std::cout << "行 " << i + 1 << " の合計: " << sum << std::endl; // 合計を表示
}
return 0;
}
行 1 の合計: 6
行 2 の合計: 15
行 3 の合計: 24
4. 2次元配列を使った画像処理
2次元配列は、画像データの表現にも使用されます。
以下のコードでは、簡単なグレースケール画像を表現し、明るさを調整しています。
#include <iostream>
#include <vector>
int main() {
// グレースケール画像を表現する2次元配列
std::vector<std::vector<int>> image = {
{100, 150, 200},
{50, 75, 100},
{0, 25, 50}
};
// 明るさを調整
int brightnessAdjustment = 50;
for (int i = 0; i < image.size(); ++i) {
for (int j = 0; j < image[i].size(); ++j) {
image[i][j] = std::min(255, image[i][j] + brightnessAdjustment); // 明るさを調整
}
}
// 調整後の画像を表示
for (const auto& row : image) {
for (const auto& pixel : row) {
std::cout << pixel << " "; // 各ピクセルを表示
}
std::cout << std::endl; // 行の終わりで改行
}
return 0;
}
150 200 250
100 125 150
50 75 100
このように、vector
を使用した2次元配列は、さまざまな応用が可能であり、特にデータの表現や計算において非常に便利です。
実践例:vectorで2次元配列を使ったプログラム
ここでは、C++のvector
を使用して2次元配列を活用した実践的なプログラムの例を紹介します。
このプログラムでは、簡単な成績管理システムを作成し、学生の成績を管理・表示します。
プログラムの概要
- 学生の数と科目の数を指定し、各学生の成績を2次元配列で管理します。
- 成績を入力し、各学生の平均点を計算して表示します。
コード例
#include <iostream>
#include <vector>
#include <iomanip> // std::setprecisionを使用するために必要
int main() {
int numStudents, numSubjects;
// 学生数と科目数の入力
std::cout << "学生の数を入力してください: ";
std::cin >> numStudents;
std::cout << "科目の数を入力してください: ";
std::cin >> numSubjects;
// 2次元配列を生成
std::vector<std::vector<int>> grades(numStudents, std::vector<int>(numSubjects));
// 成績の入力
for (int i = 0; i < numStudents; ++i) {
std::cout << "学生 " << (i + 1) << " の成績を入力してください:\n";
for (int j = 0; j < numSubjects; ++j) {
std::cout << "科目 " << (j + 1) << ": ";
std::cin >> grades[i][j]; // 成績を入力
}
}
// 各学生の平均点を計算して表示
std::cout << std::fixed << std::setprecision(2); // 小数点以下2桁まで表示
for (int i = 0; i < numStudents; ++i) {
int sum = 0;
for (int j = 0; j < numSubjects; ++j) {
sum += grades[i][j]; // 成績を合計
}
double average = static_cast<double>(sum) / numSubjects; // 平均を計算
std::cout << "学生 " << (i + 1) << " の平均点: " << average << std::endl; // 平均点を表示
}
return 0;
}
プログラムの説明
- 学生数と科目数の入力: ユーザーから学生の数と科目の数を入力してもらいます。
- 2次元配列の生成:
vector
を使用して、学生数×科目数の2次元配列を生成します。 - 成績の入力: 各学生の成績を入力します。
- 平均点の計算: 各学生の成績を合計し、平均点を計算して表示します。
以下は、プログラムを実行した際の例です。
学生の数を入力してください: 2
科目の数を入力してください: 3
学生 1 の成績を入力してください:
科目 1: 80
科目 2: 90
科目 3: 85
学生 2 の成績を入力してください:
科目 1: 70
科目 2: 75
科目 3: 80
学生 1 の平均点: 85.00
学生 2 の平均点: 75.00
このプログラムは、vector
を使用した2次元配列の実践的な利用例を示しており、成績管理の基本的な機能を実装しています。
vector
の特性を活かすことで、動的にサイズを変更できる柔軟なデータ構造を利用しています。
よくあるエラーとその対処法
C++のvector
を使用した2次元配列のプログラミングでは、いくつかの一般的なエラーが発生することがあります。
ここでは、よくあるエラーとその対処法について解説します。
1. インデックスの範囲外アクセス
エラー内容
vector
のインデックスが範囲外の場合、プログラムがクラッシュすることがあります。
たとえば、存在しない行や列にアクセスしようとすると、未定義の動作が発生します。
対処法
インデックスが有効な範囲内であることを確認するために、条件文を使用してチェックします。
以下のように、インデックスを使用する前にサイズを確認することが重要です。
if (i >= 0 && i < array.size() && j >= 0 && j < array[i].size()) {
// 有効なインデックスの場合の処理
}
2. 初期化されていない要素の使用
エラー内容
vector
の要素を初期化せずに使用すると、未定義の値が出力されることがあります。
特に、数値型の要素は初期化されていない場合、ゴミ値が含まれることがあります。
対処法
vector
を初期化する際に、デフォルト値を指定することができます。
以下のように、初期化時に値を設定することで、未定義の値を防ぐことができます。
std::vector<std::vector<int>> array(rows, std::vector<int>(cols, 0)); // すべての要素を0で初期化
3. メモリ不足エラー
エラー内容
非常に大きな2次元配列を作成しようとすると、メモリ不足エラーが発生することがあります。
特に、vector
は動的にメモリを確保するため、サイズが大きくなると問題が発生します。
対処法
必要なサイズを見積もり、メモリの使用量を最適化することが重要です。
また、プログラムの実行環境に応じて、メモリ制限を確認し、適切なサイズの配列を使用するようにします。
4. 行数や列数の不一致
エラー内容
2次元配列を操作する際に、行数や列数が一致しない場合、計算や表示が正しく行われないことがあります。
たとえば、行列の加算を行う際に、サイズが異なるとエラーが発生します。
対処法
行数や列数が一致していることを確認するために、条件文を使用してチェックします。
以下のように、サイズを比較することが重要です。
if (matrixA.size() == matrixB.size() && matrixA[0].size() == matrixB[0].size()) {
// 行列の加算処理
}
5. 参照の無効化
エラー内容
vector
の要素を参照している場合、元のvector
が変更されると、参照が無効になることがあります。
これにより、予期しない動作が発生することがあります。
対処法
参照を使用する際は、元のvector
が変更されないことを確認するか、必要に応じてコピーを作成することが重要です。
以下のように、コピーを作成することで安全に操作できます。
std::vector<int> copy = originalVector; // コピーを作成
これらのエラーとその対処法を理解することで、C++のvector
を使用した2次元配列のプログラミングがよりスムーズに行えるようになります。
エラーを事前に防ぐためのチェックを行い、適切な初期化やサイズ管理を心がけましょう。
まとめ
この記事では、C++のvector
を使用して2次元配列を生成し、操作する方法について詳しく解説しました。
基本的な使い方から応用的な利用法、実践例、よくあるエラーとその対処法まで幅広く取り上げ、実際のプログラミングに役立つ情報を提供しました。
これを機に、2次元配列を活用したプログラムを自分で作成し、さらなるスキル向上に挑戦してみてください。