[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
を活用し、より柔軟なデータ管理を実践してみてはいかがでしょうか。