C++で与えられた行列を対角行列に変換するプログラムの作成方法
n×n のサイズで与えられた行列を、種類を問わず対角行列へ変換するのが本記事のテーマです。C++による実装方法を、考え方・アルゴリズム・サンプルコード・実行結果まで含めてわかりやすく解説します。
対角行列とは?
対角行列とは、n×n の正方行列のうち、対角成分(行番号と列番号が一致する要素)以外のすべての要素が 0 である行列を指します。対角成分自体には任意の値を入れることができます。
下図は、非対角成分を 0 に変換するイメージです。
| 1 2 3 | | 1 0 3 | | 4 5 6 | → | 0 5 0 | | 7 8 9 | | 7 0 9 |
変換のアプローチ
変換の手順は非常にシンプルです。行列内の全要素を二重ループで走査し、i と j が一致しない要素(非対角成分)を見つけたら 0 に置き換えます。対角成分(i == j の要素)は元の値のまま変更しません。
入力例と出力例
例 1
入力:matrix[3][3] = {{ 1, 2, 3 },
{ 4, 5, 6 },
{ 7, 8, 9 }}
出力:{{ 1, 0, 3 },
{ 0, 5, 0 },
{ 7, 0, 9 }}
例 2
入力:matrix[3][3] = {{ 91, 32, 23 },
{ 40, 51, 26 },
{ 72, 81, 93 }}
出力:{{ 91, 0, 23 },
{ 0, 51, 0 },
{ 72, 0, 93 }}
アルゴリズム
開始
ステップ 1 → 行列のサイズを定数として定義する(const int n = 10)
ステップ 2 → 対角行列へ変換する関数を用意する
void diagonal(int arr[][n], int a, int m)
ループ(int i = 0; i < a; i++)
ループ(int j = 0; j < m; j++)
もし i != j なら
arr[i][j] に 0 を代入
条件終了
ループ終了
ループ終了
ループ(int i = 0; i < a; i++)
ループ(int j = 0; j < m; j++)
arr[i][j] を出力
ループ終了
改行を出力
ループ終了
ステップ 3 → main() 内の処理
行列を宣言する:int arr[][n] = {{ 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 }}
関数を呼び出す:diagonal(arr, 3, 3)
終了
C++ サンプルコード
#include <iostream>
using namespace std;
const int n = 10;
// n×n 行列の非対角成分を 0 に置き換える関数
void diagonal(int arr[][n], int a, int m) {
// 非対角成分を 0 にする
for (int i = 0; i < a; i++) {
for (int j = 0; j < m; j++) {
if (i != j)
arr[i][j] = 0;
}
}
// 変換後の行列を表示する
for (int i = 0; i < a; i++) {
for (int j = 0; j < m; j++) {
cout << arr[i][j] << " ";
}
cout << endl;
}
}
int main() {
int arr[][n] = { { 1, 2, 3 },
{ 4, 5, 6 },
{ 7, 8, 9 } };
diagonal(arr, 3, 3);
return 0;
}
実行結果
上記のコードをコンパイルして実行すると、次の出力が得られます。
1 0 3 0 5 0 7 0 9
コードのポイント
- 条件「i != j」 … 行と列の番号が異なる要素=非対角成分なので、0 に置き換えています。
- 時間計算量 O(n²) … 行列の全要素を 1 回ずつ走査するためです。
- 空間計算量 O(1) … 元の配列を直接書き換えるため、追加のメモリが不要です。
なお、主対角線に加えて反対角線(右上がりの対角線)も残したい場合は、条件を「i != j && i + j != a - 1」に変更すれば対応できます。このように、二重ループとひとつの条件分岐だけで、任意の正方行列を簡単に対角行列へ変換することが可能です。
-
C++で対角行列・スカラー行列を判定するプログラムの書き方
行列 M[r][c] が与えられたとき、「r」は行数、「c」は列数を表し、r = c のとき正方行列となります。本記事では、与えられた正方行列が対角行列であるか、スカラー行列であるかを判定し、該当する場合には「yes」を出力する方法を解説します。 対角行列とは 正方行列 m[][] が対角行列であるのは、主対角線以外の要素がすべてゼロである場合、かつその場合に限ります。 下図のように、赤色で示された要素が主対角成分(非ゼロ)であり、それ以外の要素はすべてゼロになっているため、この行列は対角行列です。 入出力例 Input: m[3][3] = { {7, 0, 0}, {0, 8, 0}
-
C++でグラフの隣接行列を実装する方法【サンプルコード付き解説】
隣接行列とは グラフの隣接行列(Adjacency Matrix)とは、V×Vのサイズを持つ正方行列のことです。ここでVはグラフGの頂点数を表します。行列の行と列にはそれぞれ頂点が対応付けられ、頂点iから頂点jへの辺が存在する場合は、i行目・j列目の要素に1が格納されます(重み付きグラフの場合は、辺の重みなどの非ゼロの値が入ります)。辺が存在しない場合は0が格納されます。 なお、無向グラフの場合、辺は双方向につながりを持つため、隣接行列は必ず対称行列になります。つまり、adj[i][j]とadj[j][i]は常に同じ値となります。 隣接行列表現の計算量 空間計算量: 隣接行列にはO(V²)