Aizu Online Judge(AOJ)が提供している「プログラミング入門」(ITP1)の7_D問題をC++とPython で解いてみました。
ITP1 のトピック7では、再び構造化プログラムについて学びます。「繰り返し処理や配列を組み合わせることで、構造化プログラミングの理解を深めます。」とあります。この学習コースを通じて、Python に慣れていきたいと考えています。
問題(7_D: Matrix Multiplication)
問題はリンク先をご覧ください。
AOJ ITP1 7_D問題:Matrix Multiplication
行列の積を計算します。
解答案
ITP1 の問題6_D で行列とベクトルの積を求めました。今回は、行列と行列の積を求めます。
行列
初めて見る方は、複雑な式だと感じるかもしれません。
C++ プログラム例(ITP1 7_D)
2次元配列で行列を表現して、前述の行列の積の定義に従って、計算するだけです。
問題文および上の解説では、添え字を1から記しましたが、以下のプログラムは、無駄な配列が出ないように添え字を0から使っています。これは、問題6_Dの場合と同じです。
#include <iostream>
using namespace std;
int main()
{
int n, m, l;
cin >> n >> m >> l;
int a[n][m], b[m][l];
for (int i = 0; i < n; ++i) {
for (int j = 0; j < m; ++j) {
cin >> a[i][j];
}
}
for (int j = 0; j < m; ++j) {
for (int k = 0; k < l; ++k) {
cin >> b[j][k];
}
}
for (int i = 0; i < n; ++i) {
for (int k = 0; k < l; ++k) {
long long int answer = 0;
for (int j = 0; j < m; ++j) {
answer += a[i][j] * b[j][k];
}
cout << answer << " \n"[k == l - 1];
}
}
return 0;
}
Python プログラム例(ITP1 7_D)
Python では、リストを使います。行列の演算については、NumPy という拡張モジュールを使うこともできますが、素の Python の範囲で実装しました。
変数
n, m, l = map(int, input().split())
a = [[0 for i in range(m)] for j in range(n)]
b = [[0 for i in range(l)] for j in range(m)]
c = [[0 for i in range(l)] for j in range(n)]
for i in range(n):
a[i] = list(map(int, input().split()))
for i in range(m):
b[i] = list(map(int, input().split()))
for i in range(n):
for j in range(l):
for k in range(m):
c[i][j] += a[i][k] * b[k][j]
for i in range(n):
print(*c[i])
上記プログラムは、すべて AOJ で「AC(Accepted=正解)」と判定されます。
最後に
構造化プログラムの応用として、行列の積を計算しました。行列の演算は、昔は高校数学として履修していました。今は大学で線形代数という科目で学ぶ方が多いと思われます。
トピック7まで進み、プログラムできる範囲が広がりました。
引き続き、ITP1 の問題を紹介していきます。