行列の和、差 、積

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
なへもん

行列の和、差 、積

#1

投稿記事 by なへもん » 8年前

以下の機能を持つぷろぐらむを、「プログラム作成の系統的な手順」に従って作成せよ。
指定された3x3の行列(行列1または行列2)に値を入力する
行列1+行列2を求めて行列3に入れます
行列1-行列2を求めて行列3に入れます
行列1x行列2を求めて行列3に入れます
行列1、行列2、または行列3(計算結果を保持)を表示する
行列1x行列2の中間式を表示する。なお、負の数は()で囲むこと
プログラムを終了する
5種類の機能を個別に実行できるようにすること
行列の要素はint型
行列の要素の初期値は0
行列の積C=AxBにおける計算式を以下に示す。






(演習問題の考え方)

関数
主プログラム(main)
指定された行列を入力する(getMatrix)
指定された行列を表示する(showMatrix)
行列の和を求める(addMatrix)
行列の差を求める(subtractMatrix)
行列の積を求める(multiplyMatrix)
行列の積の中間結果を表示する(showMultiplicationFormula)
機能を一覧表示する(showMenu)


教えてください。

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: 行列の和、差 、積

#2

投稿記事 by みけCAT » 8年前

Exercises in Programmingの問題ですね?
課題の丸投げは禁止です。
また、「プログラム作成の系統的な手順」を知らないし、ググっても出なかったのでわかりません。

質問がある場合は、フォーラムルールに従い、具体的にお願いします。

フォーラムルールより転載
どう質問していいか解らない時は、以下のテンプレをコピペして、

各項目に対して答える形で記載して下さい。

[hr]
[1] 質問文
 [1.1] 自分が今行いたい事は何か
 [1.2] どのように取り組んだか(プログラムコードがある場合記載)
 [1.3] どのようなエラーやトラブルで困っているか(エラーメッセージが解る場合は記載)
 [1.4] 今何がわからないのか、知りたいのか

[2] 環境  
 [2.1] OS : Windows, Linux等々
 [2.2] コンパイラ名 : VC++ 2008EE, Borand C++, gcc等々

[3] その他
 ・どの程度C言語を理解しているか
 ・ライブラリを使っている場合は何を使っているか

[hr]
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

Math

Re: 行列の和、差 、積

#3

投稿記事 by Math » 8年前

[参考までに」

コード:

-------------------------------------------------------------- [加算]
宣言 VECTOR VAdd( VECTOR In1, VECTOR In2 ) ;

 
概略 二つのベクトルを加算する

 
引数 VECTOR In1 : 加算されるベクトル
VECTOR In2 : 加算するベクトル  
戻り値 In1 と In2 の値を加算した VECTOR 構造体 
解説  引数 In1 と In2 の x, y, z 成分を加算した結果を戻り値として返す関数です。
戻り値.x = In1.x + In2.x ;
戻り値.y = In1.y + In2.y ;
戻り値.z = In1.z + In2.z ;


 
 
サンプル

  VECTOR 構造体 Vect1 と Vect2 を加算して、結果を Vect1 に代入します。

#include "DxLib.h"

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
    VECTOR Vect1, Vect2 ;

    // DXライブラリの初期化
    if( DxLib_Init() < 0 )
    {
        // エラーが発生したら直ちに終了
        return -1 ;
    }

    // Vect1 と Vect2 に値を代入
    Vect1 = VGet( 100.0f, 200.0f, 500.0f ) ;
    Vect2 = VGet( 30.0f, 100.0f, 80.0f ) ;

    // Vect1 と Vect2 を加算して結果を Vect1 に代入
    Vect1 = VAdd( Vect1, Vect2 ) ;

    // Vect1 の内容を画面に表示
    DrawFormatString( 0, 0, GetColor( 255,255,255 ), "Vect1  x=%f y=%f z=%f", Vect1.x, Vect1.y, Vect1.z ) ;  

    // キー入力待ち
    WaitKey() ;

    // DXライブラリの後始末
    DxLib_End() ;

    // ソフトの終了
    return 0 ;
}
-------------------------------------------------------------- [減算]
宣言 VECTOR VSub( VECTOR In1, VECTOR In2 ) ;

 
概略 二つのベクトルを減算する

 
引数 VECTOR In1 : 減算されるベクトル
VECTOR In2 : 減算するベクトル  
戻り値 In1 から In2 の値を減算した VECTOR 構造体 
解説  引数 In1 から In2 の x, y, z 成分を減算した結果を戻り値として返す関数です。
戻り値.x = In1.x - In2.x ;
戻り値.y = In1.y - In2.y ;
戻り値.z = In1.z - In2.z ;


 
 
サンプル

  VECTOR 構造体 Vect1 から Vect2 を減算して、結果を Vect1 に代入します。

#include "DxLib.h"

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
    VECTOR Vect1, Vect2 ;

    // DXライブラリの初期化
    if( DxLib_Init() < 0 )
    {
        // エラーが発生したら直ちに終了
        return -1 ;
    }

    // Vect1 と Vect2 に値を代入
    Vect1 = VGet( 100.0f, 200.0f, 500.0f ) ;
    Vect2 = VGet( 30.0f, 100.0f, 80.0f ) ;

    // Vect1 から Vect2 を減算して結果を Vect1 に代入
    Vect1 = VSub( Vect1, Vect2 ) ;

    // Vect1 の内容を画面に表示
    DrawFormatString( 0, 0, GetColor( 255,255,255 ), "Vect1  x=%f y=%f z=%f", Vect1.x, Vect1.y, Vect1.z ) ;  

    // キー入力待ち
    WaitKey() ;

    // DXライブラリの後始末
    DxLib_End() ;

    // ソフトの終了
    return 0 ;
}
-------------------------------------------------------------- [乗算]
宣言 MATRIX MMult( MATRIX In1, MATRIX In2 ) ;

 
概略 二つの行列の乗算を行う

 
引数 MATRIX In1 : 乗算する左側の行列
MATRIX In2 : 乗算する右側の行列
 
戻り値 乗算した結果の行列 
解説  引数 In1 と In2 を乗算した結果の行列を戻り値として返す関数です。
  行列と行列の乗算は複数の行列の効果を合成することができます。 ( 合成された行列は In1 → In2 の順で効果が現れます( 例:拡大行列と平行移動行列を乗算した場合、 その行列を使用して変換( VTransform )したベクトルは拡大行列→平行移動行列の順で変換( VTransform )した場合と同じ結果になります ) )
戻り値行列
m[0][0] = In1.m[0][0] * In2.m[0][0] + In1.m[0][1] * In2.m[1][0] +
          In1.m[0][2] * In2.m[2][0] + In1.m[0][3] * In2.m[3][0] ;
m[0][1] = In1.m[0][0] * In2.m[0][1] + In1.m[0][1] * In2.m[1][1] +
          In1.m[0][2] * In2.m[2][1] + In1.m[0][3] * In2.m[3][1] ;
m[0][2] = In1.m[0][0] * In2.m[0][2] + In1.m[0][1] * In2.m[1][2] +
          In1.m[0][2] * In2.m[2][2] + In1.m[0][3] * In2.m[3][2] ;
m[0][3] = In1.m[0][0] * In2.m[0][3] + In1.m[0][1] * In2.m[1][3] +
          In1.m[0][2] * In2.m[2][3] + In1.m[0][3] * In2.m[3][3] ;

m[1][0] = In1.m[1][0] * In2.m[0][0] + In1.m[1][1] * In2.m[1][0] +
          In1.m[1][2] * In2.m[2][0] + In1.m[1][3] * In2.m[3][0] ;
m[1][1] = In1.m[1][0] * In2.m[0][1] + In1.m[1][1] * In2.m[1][1] +
          In1.m[1][2] * In2.m[2][1] + In1.m[1][3] * In2.m[3][1] ;
m[1][2] = In1.m[1][0] * In2.m[0][2] + In1.m[1][1] * In2.m[1][2] +
          In1.m[1][2] * In2.m[2][2] + In1.m[1][3] * In2.m[3][2] ;
m[1][3] = In1.m[1][0] * In2.m[0][3] + In1.m[1][1] * In2.m[1][3] +
          In1.m[1][2] * In2.m[2][3] + In1.m[1][3] * In2.m[3][3] ;

m[2][0] = In1.m[2][0] * In2.m[0][0] + In1.m[2][1] * In2.m[1][0] +
          In1.m[2][2] * In2.m[2][0] + In1.m[2][3] * In2.m[3][0] ;
m[2][1] = In1.m[2][0] * In2.m[0][1] + In1.m[2][1] * In2.m[1][1] +
          In1.m[2][2] * In2.m[2][1] + In1.m[2][3] * In2.m[3][1] ;
m[2][2] = In1.m[2][0] * In2.m[0][2] + In1.m[2][1] * In2.m[1][2] +
          In1.m[2][2] * In2.m[2][2] + In1.m[2][3] * In2.m[3][2] ;
m[2][3] = In1.m[2][0] * In2.m[0][3] + In1.m[2][1] * In2.m[1][3] +
          In1.m[2][2] * In2.m[2][3] + In1.m[2][3] * In2.m[3][3] ;

m[3][0] = In1.m[3][0] * In2.m[0][0] + In1.m[3][1] * In2.m[1][0] +
          In1.m[3][2] * In2.m[2][0] + In1.m[3][3] * In2.m[3][0] ;
m[3][1] = In1.m[3][0] * In2.m[0][1] + In1.m[3][1] * In2.m[1][1] +
          In1.m[3][2] * In2.m[2][1] + In1.m[3][3] * In2.m[3][1] ;
m[3][2] = In1.m[3][0] * In2.m[0][2] + In1.m[3][1] * In2.m[1][2] +
          In1.m[3][2] * In2.m[2][2] + In1.m[3][3] * In2.m[3][2] ;
m[3][3] = In1.m[3][0] * In2.m[0][3] + In1.m[3][1] * In2.m[1][3] +
          In1.m[3][2] * In2.m[2][3] + In1.m[3][3] * In2.m[3][3] ;


 
 
サンプル

  ベクトルをY軸回転90度する行列とY軸回転-90度する2倍に拡大する行列を乗算して
 ベクトルに対してY軸回転行列→2倍拡大行列の順で VTransform を使用した場合と同じ効果がある行列を作成します。 
#include "DxLib.h"

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
    MATRIX Matrix, Matrix1, Matrix2 ;
    VECTOR Vect1, Vect2 ;

    // DXライブラリの初期化
    if( DxLib_Init() < 0 )
    {
        // エラーが発生したら直ちに終了
        return -1 ;
    }

    // Y軸回転90度する行列とY軸回転-90度する行列を作成
    Matrix1 = MGetRotY(  DX_PI_F / 2.0f ) ;
    Matrix2 = MGetRotY( -DX_PI_F / 2.0f ) ;

    // 二つの行列を0.5倍して加算したものを Matrix に代入
    Matrix = MAdd( MScale( Matrix1, 0.5f ), MScale( Matrix2, 0.5f ) ) ;

    // 適当な値を Vect1 に代入
    Vect1 = VGet( 200.0f, 0.0f, 0.0f ) ;

    // Vect1 を Matrix3 を使用して変換した値を Vect2 に代入
    Vect2 = VTransform( Vect1, Matrix ) ;

    // Matrix1 の値を画面に表示
    DrawString( 0, 0, "Y軸90度回転行列", GetColor( 255,255,255 ) ) ;
    DrawFormatString( 0, 16, GetColor( 255,255,255 ), "m00 %f  m01 %f  m02 %f  m03 %f",
        Matrix1.m[0][0], Matrix1.m[0][1], Matrix1.m[0][2], Matrix1.m[0][3] ) ;

    DrawFormatString( 0, 32, GetColor( 255,255,255 ), "m10 %f  m11 %f  m12 %f  m13 %f",
        Matrix1.m[1][0], Matrix1.m[1][1], Matrix1.m[1][2], Matrix1.m[1][3] ) ;

    DrawFormatString( 0, 48, GetColor( 255,255,255 ), "m20 %f  m21 %f  m22 %f  m23 %f",
        Matrix1.m[2][0], Matrix1.m[2][1], Matrix1.m[2][2], Matrix1.m[2][3] ) ;

    DrawFormatString( 0, 64, GetColor( 255,255,255 ), "m30 %f  m31 %f  m32 %f  m33 %f",
        Matrix1.m[3][0], Matrix1.m[3][1], Matrix1.m[3][2], Matrix1.m[3][3] ) ;

    // Matrix2 の値を画面に表示
    DrawString( 0, 96, "Y軸-90度回転行列", GetColor( 255,255,255 ) ) ;
    DrawFormatString( 0, 112, GetColor( 255,255,255 ), "m00 %f  m01 %f  m02 %f  m03 %f",
        Matrix2.m[0][0], Matrix2.m[0][1], Matrix2.m[0][2], Matrix2.m[0][3] ) ;

    DrawFormatString( 0, 128, GetColor( 255,255,255 ), "m10 %f  m11 %f  m12 %f  m13 %f",
        Matrix2.m[1][0], Matrix2.m[1][1], Matrix2.m[1][2], Matrix2.m[1][3] ) ;

    DrawFormatString( 0, 144, GetColor( 255,255,255 ), "m20 %f  m21 %f  m22 %f  m23 %f",
        Matrix2.m[2][0], Matrix2.m[2][1], Matrix2.m[2][2], Matrix2.m[2][3] ) ;

    DrawFormatString( 0, 160, GetColor( 255,255,255 ), "m30 %f  m31 %f  m32 %f  m33 %f",
        Matrix2.m[3][0], Matrix2.m[3][1], Matrix2.m[3][2], Matrix2.m[3][3] ) ;

    // Matrix の値を画面に表示
    DrawString( 0, 192, "乗算後の行列", GetColor( 255,255,255 ) ) ;
    DrawFormatString( 0, 208, GetColor( 255,255,255 ), "m00 %f  m01 %f  m02 %f  m03 %f",
        Matrix.m[0][0], Matrix.m[0][1], Matrix.m[0][2], Matrix.m[0][3] ) ;

    DrawFormatString( 0, 224, GetColor( 255,255,255 ), "m10 %f  m11 %f  m12 %f  m13 %f",
        Matrix.m[1][0], Matrix.m[1][1], Matrix.m[1][2], Matrix.m[1][3] ) ;

    DrawFormatString( 0, 240, GetColor( 255,255,255 ), "m20 %f  m21 %f  m22 %f  m23 %f",
        Matrix.m[2][0], Matrix.m[2][1], Matrix.m[2][2], Matrix.m[2][3] ) ;

    DrawFormatString( 0, 256, GetColor( 255,255,255 ), "m30 %f  m31 %f  m32 %f  m33 %f",
        Matrix.m[3][0], Matrix.m[3][1], Matrix.m[3][2], Matrix.m[3][3] ) ;

    // 変換元のベクトル値 Vect1 を画面に表示
    DrawString( 0, 288, "変換前のベクトル", GetColor( 255,255,255 ) ) ;
    DrawFormatString( 0, 304, GetColor( 255,255,255 ), "x=%f y=%f z=%f", Vect1.x, Vect1.y, Vect1.z ) ;

    // 変換後のベクトル値 Vect2 を画面に表示
    DrawString( 0, 336, "変換後のベクトル", GetColor( 255,255,255 ) ) ;
    DrawFormatString( 0, 352, GetColor( 255,255,255 ), "x=%f y=%f z=%f", Vect2.x, Vect2.y, Vect2.z ) ;

    // キー入力待ち
    WaitKey() ;

    // DXライブラリの後始末
    DxLib_End() ;

    // ソフトの終了
    return 0 ;
}
------------------------------------------------------------------ [おまけ逆行列]
宣言 MATRIX MInverse( MATRIX InM ) ;

 
概略 逆行列を取得する

 
引数 MATRIX InM : 逆行列を求める行列
 
戻り値 InM の逆行列 
解説  引数 InM で渡された行列の逆行列を戻り値として返す関数です。
  行列は左から乗算する場合と右から乗算する場合で結果が変化するのですが、 逆行列は元の行列で左から乗算する場合と同じ結果が右から乗算した場合に出る行列です。

 
 
サンプル

  平行移動する行列とその逆行列を用意して、適当な値を持ったベクトルが
 平行移動行列→その逆行列 の順で VTransform すれば元の値に戻るかを試します。 
#include "DxLib.h"

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
    MATRIX Matrix, Matrix2 ;
    VECTOR Vect1, Vect2, Vect3 ;

    // DXライブラリの初期化
    if( DxLib_Init() < 0 )
    {
        // エラーが発生したら直ちに終了
        return -1 ;
    }

    // 平行移動する行列を Matrix2 に代入
    Matrix2 = MGetTranslate( VGet( 200.0f, 100.0f, 80.0f ) ) ;

    // Matrix2 の逆行列を Matrix に代入
    Matrix = MInverse( Matrix2 ) ;

    // 適当な値を Vect1 に代入
    Vect1 = VGet( 200.0f, 0.0f, 0.0f ) ;

    // Vect1 を Matrix2 を使用して変換した値を Vect2 に代入
    Vect2 = VTransform( Vect1, Matrix2 ) ;

    // Vect2 を Matrix2 の逆行列である Matrix で変換したものを Vect3 に代入
    Vect3 = VTransform( Vect2, Matrix ) ;

    // Matrix2 の値を画面に表示
    DrawString( 0, 0, "平行移動行列", GetColor( 255,255,255 ) ) ;
    DrawFormatString( 0, 16, GetColor( 255,255,255 ), "m00 %f  m01 %f  m02 %f  m03 %f",
        Matrix2.m[0][0], Matrix2.m[0][1], Matrix2.m[0][2], Matrix2.m[0][3] ) ;

    DrawFormatString( 0, 32, GetColor( 255,255,255 ), "m10 %f  m11 %f  m12 %f  m13 %f",
        Matrix2.m[1][0], Matrix2.m[1][1], Matrix2.m[1][2], Matrix2.m[1][3] ) ;

    DrawFormatString( 0, 48, GetColor( 255,255,255 ), "m20 %f  m21 %f  m22 %f  m23 %f",
        Matrix2.m[2][0], Matrix2.m[2][1], Matrix2.m[2][2], Matrix2.m[2][3] ) ;

    DrawFormatString( 0, 64, GetColor( 255,255,255 ), "m30 %f  m31 %f  m32 %f  m33 %f",
        Matrix2.m[3][0], Matrix2.m[3][1], Matrix2.m[3][2], Matrix2.m[3][3] ) ;

    // Matrix の値を画面に表示
    DrawString( 0, 192, "逆行列", GetColor( 255,255,255 ) ) ;
    DrawFormatString( 0, 208, GetColor( 255,255,255 ), "m00 %f  m01 %f  m02 %f  m03 %f",
        Matrix.m[0][0], Matrix.m[0][1], Matrix.m[0][2], Matrix.m[0][3] ) ;

    DrawFormatString( 0, 224, GetColor( 255,255,255 ), "m10 %f  m11 %f  m12 %f  m13 %f",
        Matrix.m[1][0], Matrix.m[1][1], Matrix.m[1][2], Matrix.m[1][3] ) ;

    DrawFormatString( 0, 240, GetColor( 255,255,255 ), "m20 %f  m21 %f  m22 %f  m23 %f",
        Matrix.m[2][0], Matrix.m[2][1], Matrix.m[2][2], Matrix.m[2][3] ) ;

    DrawFormatString( 0, 256, GetColor( 255,255,255 ), "m30 %f  m31 %f  m32 %f  m33 %f",
        Matrix.m[3][0], Matrix.m[3][1], Matrix.m[3][2], Matrix.m[3][3] ) ;

    // 変換元のベクトル値 Vect1 を画面に表示
    DrawString( 0, 288, "変換前のベクトル", GetColor( 255,255,255 ) ) ;
    DrawFormatString( 0, 304, GetColor( 255,255,255 ), "x=%f y=%f z=%f", Vect1.x, Vect1.y, Vect1.z ) ;

    // 変換後のベクトル値 Vect2 を画面に表示
    DrawString( 0, 336, "平行移動後のベクトル", GetColor( 255,255,255 ) ) ;
    DrawFormatString( 0, 352, GetColor( 255,255,255 ), "x=%f y=%f z=%f", Vect2.x, Vect2.y, Vect2.z ) ;

    // 変換後のベクトル値 Vect3 を画面に表示
    DrawString( 0, 384, "逆行列乗算後のベクトル", GetColor( 255,255,255 ) ) ;
    DrawFormatString( 0, 400, GetColor( 255,255,255 ), "x=%f y=%f z=%f", Vect3.x, Vect3.y, Vect3.z ) ;

    // キー入力待ち
    WaitKey() ;

    // DXライブラリの後始末
    DxLib_End() ;

    // ソフトの終了
    return 0 ;
}
-------------------------------------------------------------- [おまけ算法:内積]
宣言 float VDot( VECTOR In1, VECTOR In2 ) ;

 
概略 二つのベクトルの内積を取得する

 
引数 VECTOR In1 : 内積するベクトル1
VECTOR In2 : 内積するベクトル2  
戻り値 In1 と In2 の内積値 
解説  引数 In1 と In2 の内積を返す関数です。
戻り値 = In1.x * In2.x + In1.y * In2.y + In1.z * In2.z ;


 
 
サンプル

  VECTOR 構造体 Vect1 と Vect2 の内積を画面に表示します。

#include "DxLib.h"

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
    VECTOR Vect1, Vect2 ;

    // DXライブラリの初期化
    if( DxLib_Init() < 0 )
    {
        // エラーが発生したら直ちに終了
        return -1 ;
    }

    // Vect1 と Vect2 に値を代入
    Vect1 = VGet( 100.0f, 200.0f, 500.0f ) ;
    Vect2 = VGet( 30.0f, 100.0f, 80.0f ) ;

    // Vect1 と Vect2 の内積を画面に表示
    DrawFormatString( 0, 0, GetColor( 255,255,255 ), "Dot  %f", VDot( Vect1, Vect2 ) ) ;  

    // キー入力待ち
    WaitKey() ;

    // DXライブラリの後始末
    DxLib_End() ;

    // ソフトの終了
    return 0 ;
}
-------------------------------------------------------------- [おまけ算法:外積]
宣言 float VDot( VECTOR In1, VECTOR In2 ) ;
宣言 VECTOR VCross( VECTOR In1, VECTOR In2 ) ;

 
概略 二つのベクトルの外積を取得する

 
引数 VECTOR In1 : 外積するベクトル1
VECTOR In2 : 外積するベクトル2  
戻り値 In1 と In2 の外積値 
解説  引数 In1 と In2 の外積を返す関数です。
戻り値.x = In1.y * In2.z - In1.z * In2.y ;
戻り値.y = In1.z * In2.x - In1.x * In2.z ;
戻り値.z = In1.x * In2.y - In1.y * In2.x ;


 
 
サンプル

  VECTOR 構造体 Vect1 と Vect2 の外積を画面に表示します。

#include "DxLib.h"

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
    VECTOR Vect1, Vect2 ;

    // DXライブラリの初期化
    if( DxLib_Init() < 0 )
    {
        // エラーが発生したら直ちに終了
        return -1 ;
    }

    // Vect1 と Vect2 に値を代入
    Vect1 = VGet( 100.0f, 200.0f, 500.0f ) ;
    Vect2 = VGet( 30.0f, 100.0f, 80.0f ) ;

    // Vect1 と Vect2 の外戚を Vect1 に代入
    Vect1 = VCross( Vect1, Vect2 ) ;

    // Vect1 の内容を画面に表示
    DrawFormatString( 0, 0, GetColor( 255,255,255 ), "Vect1  x=%f y=%f z=%f", Vect1.x, Vect1.y, Vect1.z ) ;  

    // キー入力待ち
    WaitKey() ;

    // DXライブラリの後始末
    DxLib_End() ;

    // ソフトの終了
    return 0 ;
}
-------------------------------------------------

Math

Re: 行列の和、差 、積

#4

投稿記事 by Math » 8年前

[Answer]
必ず自分で十分検証して下さい

コード:

#include <iostream>
using namespace std;
///定数定義/// 
#define N 3                //正方行列の次数
#define END 0             //終了
#define INPUT 1          //行列の入力
#define SHOW 2          //表示
#define ADD 3          //行列の和
#define SUB 4         //行列の差
#define MULTI 5      //行列の積
#define SHOWMULTI 6 //中間式の表示
///プロトタイプ宣言//
void showMenu(int matrix[N][N]);     //機能の一覧を表示する関数
void getMatrix(int matrix[N][N]);   //行列に値を入力する関数
void showMatrix(int matrix[N][N]); //行列を表示する関数
void addMatrix(int matrix1[N][N], int matrix2[N][N], int matrix3[N][N]);      //行列の和を求める関数
void subtractMatrix(int matrix1[N][N], int matrix2[N][N], int matrix3[N][N]); //行列の差を求める関数
void multiplyMatrix(int matrix1[N][N], int matrix2[N][N], int matrix3[N][N]); //行列の積を求める関数
void showMultiplicationFormula(int matrix1[N][N], int matrix2[N][N]);//行列の積の中間結果を表示する関数
void showMenu(void); //機能の一覧を表示する関数
///メイン関数//////////////////////////////////////////////////////////////////////////////////////////
void main(){
    int functionNo;        //機能番号
    int matrixNo;         //操作する行列番号
    int matrix1[N][N] = {//配列1
        {0, 0, 0},
        {0, 0, 0},
        {0, 0, 0},
    };              
    int matrix2[N][N] = {  //配列2
        {0, 0, 0},
        {0, 0, 0},
        {0, 0, 0},
    };               
    int matrix3[N][N] = {  //計算結果
        {0, 0, 0},
        {0, 0, 0},
        {0, 0, 0},
    };              
    
    //1.機能の一覧を表示する
    showMenu();

    //2.機能番号を入力する
    cout << "機能番号を入力してください。機能番号= ";
    cin >> functionNo;

    //3.機能番号が「終了」でない限り、以下の処理を繰り返す
    while(functionNo != END){

        //機能番号に対応する処理に分岐する
        switch(functionNo) {

            //3.1機能番号が「行列の入力」ならば、以下の処理を実行する
            case INPUT:

                //3.1.1行列番号(1=配列1 or 2=配列2)を入力する
                cout << "入力する配列は? (1 or 2) : ";
                cin >> matrixNo;

                //3.1.2指定された行列を入力する
                if(matrixNo == 1){
                    getMatrix(matrix1);
                }
                
                else if(matrixNo == 2){
                    getMatrix(matrix2);
                }

                else{
                    cout << "配列番号がおかしいです";
                }
                break;

            //3.2機能番号が「行列の表示」ならば、以下の処理を実行する
            case SHOW:

                //3.2.1配列番号を入力する
                cout << "表示する配列は? (1, 2 or 3) : ";
                cin >> matrixNo;

                //3.2.2指定された行列を表示する
                if(matrixNo == 1){
                    showMatrix(matrix1);
                }

                else if(matrixNo == 2){
                    showMatrix(matrix2);
                }

                else if(matrixNo == 3){
                    showMatrix(matrix3);
                }

                else{
                    cout << "配列番号がおかしいです";
                }
                break;

            //3.3機能番号が「行列の和」ならば、以下の処理を実行する
            case ADD:
				addMatrix(matrix1, matrix2, matrix3);
                //addMatrix(matrix1[N][N], matrix2[N][N], matrix3[N][N]);
                break;

            //3.4機能番号が「行列の差」ならば、以下の処理を実行する
            case SUB:
                subtractMatrix(matrix1, matrix2, matrix3);
                break;

            //3.5機能番号が「行列の積」ならば、以下の処理を実行する
            case MULTI:
                multiplyMatrix(matrix1, matrix2, matrix3);
                break;

            //3.6機能番号「中間式の表示」ならば、以下の処理を実行する
            case SHOWMULTI:
                showMultiplicationFormula(matrix1, matrix2);
                break;
            
            //機能番号が0~6以外ならば、コメントを表示する
            default:
                cout << "機能番号が対応していません" << endl;
                break;
        }

        //3.7機能を一覧表示する
        showMenu();
        
        //3.8機能番号を入力する
        cout << "機能番号=";
        cin >> functionNo;
    }
}

//指定された行列に値を入力する
//////////////////////////////
void getMatrix(int matrix[N][N]){

    //1.各行rowに対して以下の処理を繰り返す
    for(int i = 0; i < N; i++){

        //1.1.当該行の各列columnに対して以下の処理を繰り返す
        for(int j = 0; j < N; j++){

            //1.1.1.指定された行列のrow行column列の要素に値を入力する
            cout << "行列の" << i << "行" << j << "列要素を入力してください:";
            
            cin >> matrix[i][j];
        }
    }
}

//指定された行列を表示する
//////////////////////////
void showMatrix(int matrix[N][N]){

    //1.各行rowに対して以下の処理を繰り返す
    for(int i = 0; i < N; i++){

        //1.1.各列columnに対して以下の処理を繰り返す
        for(int j = 0; j < N; j++){

            //1.1.1.行列のrow行 column列の要素の値を表示する:負なら()
			if(matrix[i][j] < 0){ cout << "(" << matrix[i][j] << ")" << "\t"; }
		    else{ cout << matrix[i][j] << "\t"; }
        }
        cout << endl;
    }
    cout << endl;
}

//行列の和を求める
//////////////////
void addMatrix(int matrix1[N][N], int matrix2[N][N], int matrix3[N][N]){
    
    //1.配列の各要素を加算する
    for(int i = 0; i < N; i++){
        for(int j = 0; j < N; j++){
            matrix3[i][j] = matrix1[i][j] + matrix2[i][j];
        }
    }
}

//行列の差を求める
////////////////
void subtractMatrix(int matrix1[N][N], int matrix2[N][N], int matrix3[N][N]){
    
    //1.配列の各要素を減算する
    for(int i = 0; i < N; i++){
        for(int j = 0; j < N; j++){
            matrix3[i][j] = matrix1[i][j] - matrix2[i][j];
        }
    }
}

//行列の積を求める
////////////////
void multiplyMatrix(int matrix1[N][N], int matrix2[N][N], int matrix3[N][N]){
    
    //1.各行rowに対して以下の処理を繰り返す
    for(int i = 0; i < N; i++){

        //1.1.当該行の各列columnに対して以下の処理を繰り返す
        for(int j = 0; j < N; j++){

            //1.1.1.計算結果のrow行column列を0とする
            matrix3[i][j] = 0;

            //1.1.2.変数 kの値を0~N-1まで変えながら以下の処理を繰り返す
            for(int k = 0; k < N-1; k++){

                //1.1.2.1.行列1のrow行 k列の値と行列2のk行 column列の値を乗じて、
                                           //計算結果のrow行 column列に加算する      
                int x = matrix3[i][j] + matrix1[i][k] * matrix2[k][j];
                matrix3[i][j] = x;
            }
        }
    }
}

//行列の積を求める中間式を表示する
////////////////////////////////
void showMultiplicationFormula(int matrix1[N][N], int matrix2[N][N]){

    //1.各行rowに対して以下の処理を繰り返す
    for(int i = 0; i < N; i++){

        //1.1.当該行の各列columnに対して以下の処理を繰り返す
        for(int j = 0; j < N; j++){

            //1.1.1.変数 kの値を0~N-1まで変えながら以下の処理を繰り返す
            for(int k = 0; k < N-1; k++){

                //1.1.1.1.行列1のrow行 i列の値を表示する。(負数の場合のみ()で囲む) 
                cout << matrix1[i][k];

                //1.1.1.2."*"を表示する
                cout << " * ";

                //1.1.1.3.行列2のi行 column列の値を表示する。(負数の場合のみ()で囲む) 
                cout << matrix2[k][j];

                //1.1.1.4.kがN-1でなければ "+"を表示する
                if(k != N-1){
                    cout << " + ";
                }
            }
        }

        //1.2.改行する
        cout << endl;
    }
}

//機能の一覧を表示する
//////////////////////
void showMenu(void){

    //1.機能番号の一覧を表示する
    cout << "機能番号を選択してください" << endl;
    cout << " 0 " << "プログラムの終了(END)" << endl;
    cout << " 1 " << "行列の入力(INPUT)" << endl;
    cout << " 2 " << "行列の表示(SHOW)" << endl;
    cout << " 3 " << "行列の和(ADD)" << endl;
    cout << " 4 " << "行列の差(SUB)" << endl;
    cout << " 5 " << "行列の積(MULTI)" << endl;
    cout << " 6 " << "中間式の表示(SHOWMULTI)" << endl;
}
//////////////////////////////////////////////////////////

閉鎖

“C言語何でも質問掲示板” へ戻る