こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

c言語 逆行列 掃き出し法 既約分数

c言語初心者の者です。課題がででソースコードを書き、コマンドプロンプトで入力したら、「a.exeは動作が停止しました」と出ました。恐らくスタックを消費仕切っているのだと思いますが、改善する内容がわかりません。出来れば理由込みで詳しく改善点を教えてほしいです。できるだけ簡単なプログラムで作成をお願いします。

課題内容:4行4列の逆行列を計算するプログラムを作成せよ。但し、分数は既約分数とし、分母に「-」はつけない。掃き出し法を用いて解け。更に、ポインタや構造体や特別な関数を使用してはならない。

ソースコード:

#include<stdio.h>

int gcdf(int x, int y){

return(y == 0 ? x :gcdf(y,x%y)); /*最大公約数を求める*/

}

int gcd(int a, int b){

return(a > b ? gcdf(a, b) : gcdf(a,a)); /*恐らくここも間違いの1つ、gcd(a,a)をどう
                  なおせばいいか*/

}

int main(void){

int buf[2]; /*データ保存*/
int i, j, k,g; /*カウンタ*/
int n = 4; /*配列の次数*/


int a[4][4][2] = {{{1,1},{2,1},{0,1},{1,2}}, /*問題の行列*/
{{0,1},{2,3},{1,1},{0,1}},
{{1,1},{0,1},{0,1},{-1,1}},
{{1,1},{0,1},{-1,2},{-1,1}}};

int inv_a[4][4][2] = {{{1,1},{0,1},{0,1},{0,1}}, /*単位行列*/
{{0,1},{1,1},{0,1},{0,1}},
{{0,1},{0,1},{1,1},{0,1}},
{{0,1},{0,1},{0,1},{1,1}}};


for(i = 0; i < n; i++){

buf[0] = a[i][i][1]; //分子
buf[1] = a[i][i][0]; //分母



for(j = 0; j < n; j++){
a[i][j][0] = buf[0] * a[i][j][0];
a[i][j][1] = buf[1] * a[i][j][1];

g = gcd(a[i][j][0], a[i][j][1]);

a[i][j][0] = a[i][j][0] / g;
a[i][j][1] = a[i][j][1] / g; //約分


inv_a[i][j][0] *= buf[0];
inv_a[i][j][1] *= buf[1];

g = gcd(inv_a[i][j][0], inv_a[i][j][1]);

inv_a[i][j][0] = inv_a[i][j][0] / g;
inv_a[i][j][1] = inv_a[i][j][1] / g; //約分

}

for(j = 0; j < n; j++){

if(i != j)

buf[0] = a[j][i][0]; buf[1] = a[j][i][1];



for(k = 0; k < n; k++){

a[j][k][0] = a[j][k][0] * a[i][k][1] * buf[1] - a[j][k][1] * a[i][k][0] * buf[0];
a[j][k][1] = a[j][k][1] * a[i][k][1] * buf[1];

g = gcd(a[j][k][0], a[j][k][1]);

a[j][k][0] = a[j][k][0] / g;
a[j][k][1] = a[j][k][1] / g;


inv_a[j][k][0] = inv_a[j][k][0] * inv_a[i][k][1] * buf[1] - inv_a[j][k][1]* inv_a[i][k][0] * buf[0];

inv_a[j][k][1] = inv_a[j][k][1] * inv_a[i][k][1] * buf[1];

g = gcd(inv_a[j][k][0], inv_a[j][k][1]);

inv_a[j][k][0] = inv_a[j][k][0] / g;
inv_a[j][k][1] = inv_a[j][k][1] / g;

}}}





printf("1 2 0 1/2 \n 0 2/3 1 0 \n 1 0 0 -1 \n 1 0 -1/2 -1 \n の逆行列は以下の通り");

for(i = 0; i < n; i++){ /*逆行列出力*/
for(j = 0; j < n; j++){

if(inv_a[i][j][1] = 0){
inv_a[i][j][0] *= (-1);
inv_a[i][j][1] *= (-1); /*分母のマイナスをプラスに*/



}

/*分母が1の時に整数表示*/


if(inv_a[i][j][1] != 1)

printf("%d/%d", inv_a[i][j][0],inv_a[i][j][1]);


else

printf("%d", inv_a[i][j][0]);


}
}



return 0;
}

投稿日時 - 2018-01-20 14:32:23

QNo.9420320

すぐに回答ほしいです

質問者が選んだベストアンサー

答えはちゃんと出ないけど、全体的によく書けていますね。コピペで済まそうとする初心者とは俺は違うんだという気迫が伝わります。

こーかな?
https://ideone.com/qJx6Rq

#修正したところどこだか忘れて、理由付け忘れている所あるかもしれないという不安を抱えつつ。

投稿日時 - 2018-01-21 10:07:36

お礼

ありがとうございます。ソースコードをもう一回みて勉強します。ありがとうございました。

投稿日時 - 2018-01-21 11:03:13

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(1)