[C++] vector二次元配列ではpush_back()をどう使う?
C++で二次元配列を扱う際、std::vectorを使用することで動的な配列を作成できます。
二次元配列はstd::vector<std::vector<T>>のように定義します。
新しい行を追加するには、外側のvectorに対してpush_back()を使用します。
例えば、std::vector<int> newRow;を作成し、必要な要素をnewRowに追加した後、matrix.push_back(newRow);とすることで新しい行を追加できます。
この方法により、柔軟に行や列を追加・削除することが可能です。
二次元vectorでのpush_back()の基本的な使い方
push_back()の役割と基本構文
push_back()は、C++のSTL(Standard Template Library)におけるvectorクラスのメンバ関数で、vectorの末尾に新しい要素を追加するために使用されます。
これにより、動的に配列のサイズを変更することが可能です。
基本構文は以下の通りです。
#include <vector>
std::vector<int> vec;
vec.push_back(10); // 10をvecの末尾に追加このように、push_back()を使うことで、vectorに要素を追加することができます。
一次元vectorへのpush_back()
一次元のvectorに対してpush_back()を使用する場合、追加したい要素を引数として渡します。
以下に例を示します。
#include <vector>
#include <iostream>
int main() {
std::vector<int> numbers;
numbers.push_back(1); // 1を追加
numbers.push_back(2); // 2を追加
numbers.push_back(3); // 3を追加
for (int num : numbers) {
std::cout << num << " ";
}
return 0;
}1 2 3この例では、numbersというvectorに対して、push_back()を使って順に1, 2, 3を追加しています。
二次元vectorへのpush_back()の方法
二次元のvectorは、vectorの中にvectorを持つ構造です。
push_back()を使って行を追加する方法を以下に示します。
#include <vector>
#include <iostream>
int main() {
std::vector<std::vector<int>> matrix;
std::vector<int> row1 = {1, 2, 3};
std::vector<int> row2 = {4, 5, 6};
matrix.push_back(row1); // row1を追加
matrix.push_back(row2); // row2を追加
for (const auto& row : matrix) {
for (int num : row) {
std::cout << num << " ";
}
std::cout << std::endl;
}
return 0;
}1 2 3
4 5 6この例では、matrixという二次元vectorに対して、row1とrow2をpush_back()で追加しています。
push_back()を使う際の注意点
- メモリの再確保:
vectorの容量が不足すると、push_back()は内部的にメモリを再確保します。
これにより、パフォーマンスが低下する可能性があります。
- 例外の考慮: メモリ不足などで
push_back()が失敗する場合、例外がスローされることがあります。
例外処理を考慮することが重要です。
- 初期化の確認: 二次元
vectorを使用する際、各行のvectorが適切に初期化されていることを確認する必要があります。
未初期化のvectorに対してpush_back()を行うと、予期しない動作を引き起こす可能性があります。
これらの点に注意しながら、push_back()を効果的に活用することが重要です。
二次元vectorにおけるpush_back()の実践
行を追加する方法
二次元vectorに新しい行を追加するには、vectorのvectorをpush_back()で追加します。
以下の例では、空の二次元vectorに行を追加しています。
#include <vector>
#include <iostream>
int main() {
std::vector<std::vector<int>> matrix;
std::vector<int> newRow = {7, 8, 9};
matrix.push_back(newRow); // newRowを追加
for (const auto& row : matrix) {
for (int num : row) {
std::cout << num << " ";
}
std::cout << std::endl;
}
return 0;
}7 8 9この例では、newRowというvectorをmatrixに追加し、新しい行として扱っています。
列を追加する方法
二次元vectorに列を追加するには、各行に対して要素を追加する必要があります。
以下の例では、既存の行に新しい要素を追加して列を増やしています。
#include <vector>
#include <iostream>
int main() {
std::vector<std::vector<int>> matrix = {{1, 2}, {3, 4}, {5, 6}};
for (auto& row : matrix) {
row.push_back(0); // 各行に0を追加
}
for (const auto& row : matrix) {
for (int num : row) {
std::cout << num << " ";
}
std::cout << std::endl;
}
return 0;
}1 2 0
3 4 0
5 6 0この例では、各行に0を追加することで、列を増やしています。
既存の行に要素を追加する方法
既存の行に要素を追加するには、その行を指定してpush_back()を使用します。
以下の例では、特定の行に要素を追加しています。
#include <vector>
#include <iostream>
int main() {
std::vector<std::vector<int>> matrix = {{1, 2, 3}, {4, 5, 6}};
matrix[0].push_back(10); // 1行目に10を追加
for (const auto& row : matrix) {
for (int num : row) {
std::cout << num << " ";
}
std::cout << std::endl;
}
return 0;
}1 2 3 10
4 5 6この例では、matrixの1行目に10を追加しています。
push_back()を使った動的配列の構築
push_back()を使うことで、動的に配列を構築することができます。
以下の例では、ユーザーからの入力に基づいて二次元vectorを構築しています。
#include <vector>
#include <iostream>
int main() {
std::vector<std::vector<int>> matrix;
int rows, cols, value;
std::cout << "行数を入力してください: ";
std::cin >> rows;
std::cout << "列数を入力してください: ";
std::cin >> cols;
for (int i = 0; i < rows; ++i) {
std::vector<int> row;
for (int j = 0; j < cols; ++j) {
std::cout << "値を入力してください: ";
std::cin >> value;
row.push_back(value);
}
matrix.push_back(row);
}
for (const auto& row : matrix) {
for (int num : row) {
std::cout << num << " ";
}
std::cout << std::endl;
}
return 0;
}行数を入力してください: 2
列数を入力してください: 2
値を入力してください: 1
値を入力してください: 2
値を入力してください: 3
値を入力してください: 4
1 2
3 4この例では、ユーザーの入力に基づいて二次元vectorを動的に構築しています。
push_back()を使うことで、行と列のサイズを動的に変更することが可能です。
応用例
動的に行列を拡張するプログラム
動的に行列を拡張するプログラムは、データの追加や削除が頻繁に行われるアプリケーションで役立ちます。
以下の例では、ユーザーの入力に基づいて行列を動的に拡張します。
#include <vector>
#include <iostream>
int main() {
std::vector<std::vector<int>> matrix;
int choice, value;
while (true) {
std::cout << "1: 行を追加, 2: 終了: ";
std::cin >> choice;
if (choice == 2) break;
std::vector<int> newRow;
std::cout << "新しい行の要素を入力 (終了は-1): ";
while (true) {
std::cin >> value;
if (value == -1) break;
newRow.push_back(value);
}
matrix.push_back(newRow);
}
for (const auto& row : matrix) {
for (int num : row) {
std::cout << num << " ";
}
std::cout << std::endl;
}
return 0;
}1: 行を追加, 2: 終了: 1
新しい行の要素を入力 (終了は-1): 1 2 3 -1
1: 行を追加, 2: 終了: 1
新しい行の要素を入力 (終了は-1): 4 5 6 -1
1: 行を追加, 2: 終了: 2
1 2 3
4 5 6このプログラムでは、ユーザーが行を追加するたびに新しい行がmatrixに追加されます。
データの読み込みと動的配列への格納
ファイルや外部データソースからデータを読み込み、動的配列に格納することは、データ処理アプリケーションでよく行われます。
以下の例では、標準入力からデータを読み込み、二次元vectorに格納します。
#include <vector>
#include <iostream>
#include <sstream>
int main() {
std::vector<std::vector<int>> data;
std::string line;
std::cout << "データを入力してください (行ごとにスペース区切り、終了は空行):" << std::endl;
while (std::getline(std::cin, line) && !line.empty()) {
std::istringstream iss(line);
std::vector<int> row;
int num;
while (iss >> num) {
row.push_back(num);
}
data.push_back(row);
}
for (const auto& row : data) {
for (int num : row) {
std::cout << num << " ";
}
std::cout << std::endl;
}
return 0;
}データを入力してください (行ごとにスペース区切り、終了は空行):
1 2 3
4 5 6
1 2 3
4 5 6このプログラムでは、ユーザーが入力したデータを行ごとに読み込み、dataという二次元vectorに格納しています。
ゲーム開発におけるマップデータの管理
ゲーム開発では、マップデータを二次元vectorで管理することが一般的です。
以下の例では、簡単なマップデータを二次元vectorで表現しています。
#include <vector>
#include <iostream>
int main() {
std::vector<std::vector<char>> map = {
{'#', '#', '#', '#', '#'},
{'#', ' ', ' ', ' ', '#'},
{'#', ' ', '#', ' ', '#'},
{'#', ' ', ' ', ' ', '#'},
{'#', '#', '#', '#', '#'}
};
for (const auto& row : map) {
for (char cell : row) {
std::cout << cell;
}
std::cout << std::endl;
}
return 0;
}#####
# #
# # #
# #
#####この例では、mapという二次元vectorを使って、簡単なマップを表現しています。
#は壁、 (スペース)は通路を示しています。
科学計算における行列演算の準備
科学計算では、行列を扱うことが多く、二次元vectorを使って行列を表現することができます。
以下の例では、行列を初期化し、表示しています。
#include <vector>
#include <iostream>
int main() {
std::vector<std::vector<double>> matrix = {
{1.0, 2.0, 3.0},
{4.0, 5.0, 6.0},
{7.0, 8.0, 9.0}
};
for (const auto& row : matrix) {
for (double num : row) {
std::cout << num << " ";
}
std::cout << std::endl;
}
return 0;
}1.0 2.0 3.0
4.0 5.0 6.0
7.0 8.0 9.0この例では、matrixという二次元vectorを使って、3×3の行列を表現しています。
GUIアプリケーションでのデータ管理
GUIアプリケーションでは、表形式のデータを管理するために二次元vectorを使用することができます。
以下の例では、簡単なデータテーブルを二次元vectorで表現しています。
#include <vector>
#include <iostream>
int main() {
std::vector<std::vector<std::string>> table = {
{"名前", "年齢", "職業"},
{"田中", "30", "エンジニア"},
{"鈴木", "25", "デザイナー"},
{"佐藤", "28", "マネージャー"}
};
for (const auto& row : table) {
for (const std::string& cell : row) {
std::cout << cell << "\t";
}
std::cout << std::endl;
}
return 0;
}名前 年齢 職業
田中 30 エンジニア
鈴木 25 デザイナー
佐藤 28 マネージャーこの例では、tableという二次元vectorを使って、簡単なデータテーブルを表現しています。
各行は異なるデータレコードを示しています。
まとめ
この記事では、C++における二次元vectorのpush_back()の使い方について詳しく解説し、基本的な操作から応用例までを紹介しました。
push_back()を活用することで、動的に配列を拡張し、さまざまなデータ構造を効率的に管理する方法を学ぶことができました。
これを機に、実際のプログラムで二次元vectorを活用し、より柔軟なデータ管理を実践してみてはいかがでしょうか。