[AIZU ONLINE JUDGE]「ITP1_7_D 行列の積」をC++で解いてみた

AIZU ONLINE JUDGE

こんにちは! mnbd(@mnbbbbbd)です。

AIZU ONLINE JUDGEの「ITP1_7_D 行列の積」を解いてみましたので、その回答と解説をご紹介いたします。

プログラミング初心者なので、もっといい回答があるに違いありません。

あくまでも「動作はする」サンプルとしてご覧ください。

問題文

n×m の行列 A と m×l の行列 B を入力し、それらの積である n×l の行列 C を出力するプログラムを作成してください。行列 C の各要素 cij は次の式で得られます:

ここで、A、B、C の各要素をそれぞれ aij、bij、cij とします。

https://onlinejudge.u-aizu.ac.jp/courses/lesson/2/ITP1/7/ITP1_7_D

入力または出力形式については上記リンクをご覧ください。

回答

#include <bits/stdc++.h>
using namespace std;

int main() {
    int n, m, l;
    cin >> n >> m >> l;
    int a[n][m] = {};
    int b[m][l] = {};
    long long c[n][l] = {};

    for(int i = 0; i < n; i++) {
        for(int j = 0; j < m; j++) {
            cin >> a[i][j];
        }
    }
    for(int i = 0; i < m; i++) {
        for(int j = 0; j < l; j++) {
            cin >> b[i][j];
        }
    }
    for(int i = 0; i < n; i++) {
        for(int j = 0; j < l; j++) {
            for(int k = 0; k < m; k++) {
                c[i][j] += a[i][k] * b[k][j];
            }
        }
    }
    for(int i = 0; i < n; i++) {
        for(int j = 0; j < l; j++) {
            cout << c[i][j];
            if(j != l - 1) {
                cout << " ";
            }
        }
        cout << endl;
    }
}

解説

最初の行の入力で行列の縦と横の値を取得できますので、入力分のaとbの多次元配列と出力になるcの多次元配列を確保して初期化してます。

後はcの行列分の2つのループとシグマの計算のための1つのループで各行列の計算をし、再度cの行列のループを回して出力してます。

私がハマったポイント

数学の問題ですが、シグマを理解していませんでした。

まずそこを調べてみて、計算するところからやりました。

それをプログラムに落とし込むわけですが、多次元配列の添字がわかりにくかったですね。

結局、添字について問題文にほぼ答えが出ているので、それに従ったという感じです。

学んだこと

学生時代にやったシグマを思い出し、またもう一度確認しました。

プログラミング的には多次元配列の添字がわかりにくく、とりあえず実行して結果をみながら修正しています。

できればプログラミングのイメージ段階で理解できることが望ましいと思います。

まとめ

AIZU ONLINE JUDGEの「ITP1_7_D 行列の積」を解いてみましたので、その回答と解説をご紹介いたしました。

私はまだ初心者ですが、よかったら一緒に勉強していきましょう。

Twitterなどをフォローしていただければ幸いです。

以上です。
読んでいただき、ありがとうございました!