配列

[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;
}

プログラムの説明

  1. 学生数と科目数の入力: ユーザーから学生の数と科目の数を入力してもらいます。
  2. 2次元配列の生成: vectorを使用して、学生数×科目数の2次元配列を生成します。
  3. 成績の入力: 各学生の成績を入力します。
  4. 平均点の計算: 各学生の成績を合計し、平均点を計算して表示します。

以下は、プログラムを実行した際の例です。

学生の数を入力してください: 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次元配列を活用したプログラムを自分で作成し、さらなるスキル向上に挑戦してみてください。

関連記事

Back to top button