- 締切済み
行列に関して。
以下の行列を対角成分が最も大きくなるような プログラムをつくりたいのですが 0 1 4 3 7 0 1 -5 1 3 0 7 -2 4 4 -8 #include<stdio.h> #include<math.h> #include<stdlib.h> #define NUM 4 int main(){ /* 初期化 */ int i; /* ループ変数 (行)*/ int j; /* ループ変数 (列)*/ int k; /* ループ変数 */ int imax; /* 最大値のi成分 */ int jmax; /* 最大値のj成分 */ double nmax; /* 最大値を入れるための変数 */ double tmp; /* ソートのための一時的な変数 */ double eps = 1.0e-6; /* 判定値 */ double a[NUM][NUM] = { { 0.0, 1.0, 4.0, 3.0}, { 7.0, 0.0, 1.0, -5.0}, { 1.0, 3.0, 0.0, 7.0}, {-2.0, 4.0, 4.0, -8.0}}; /* 対象とする要素位置 = k */ for( k = 0 ; k < NUM ; k++ ){ /*対象とする要素位置 = k*/ nmax = 0.0;/* 初期化 */ imax = k;/* 初期化 0とは限らない */ jmax = k;/* 初期化 0とは限らない */ /* 1.絶対値の最大値を求める */ for( i = k ; i < NUM ; i++ ){ for( j = k ; j < NUM ; j++ ){ if(fabs(nmax) < fabs(a[i][j])){ nmax = a[i][j]; imax = i; jmax = j; /* 対象としている行列要素の中で,最大となる行列要素のi,j成分を探す */ /*ここに絶対値の最大値を求め、nmax、imax、jmaxに代入するプログラムを書く*/ /*絶対値の求め方、数学関数fabs(x)を用いる*/ } } } /* 2.行入れ換え */ if( k != imax ){/* 対象としている行と最大値を持つ行が同じなら,入れ替える必要が無い */ for( j = 0 ; j < NUM ; j++ ){ tmp=a[k][j]; a[k][j]=a[imax][j]; a[imax][j]=tmp;/* 対象としている行と最大値を持つ行との入れ替え */ /*ここに行の入れ替え行うプログラムを書く*/ } } /* 3.列入れ換え */ if( k != jmax ){/* 対象としている列と最大値を持つ列が同じなら,入れ替える必要が無い */ for( i = 0 ; i < NUM ; i++ ){ tmp=a[i][k]; a[i][k]=a[i][imax]; a[i][imax]=tmp;/*対象としている列と最大値を持つ列との入れ替え*/ /*ここに列の入れ替え行うプログラムを書く*/ } } } /* 結果の出力 */ for(i=0; i<NUM; i++){ for(j=0; j<NUM; j++){ printf("%5.1f ",a[i][j]); } printf("\n"); } /*ここに行列の表示プログラムを書く*/ return(0); } 上のぷろぐらむを実行しても、1個目のfor文の1ループ目で終了してしまい 1行目と、4行目を交換、4列目と1列目を交換した行列だけが表示されます。 結果が以下のような行列にするにはどう改善すればよいでしょうか? -8.0 -2.0 4.0 4.0 -5.0 7.0 1.0 0.0 3.0 0.0 4.0 1.0 7.0 1.0 0.0 3.0 です。
- みんなの回答 (4)
- 専門家の回答
みんなの回答
- redfox63
- ベストアンサー率71% (1325/1856)
後者であるなら当方の環境では WinXPSP3 + VC6 お示しのコードで列入れ替えのimaxをjmaxに修正すれば 期待通りの動きになりましたよ 行入れ替えが行われているのか確認 /* 2.行入れ換え */ if( k != imax ){/* 対象としている行と最大値を持つ行が同じなら,入れ替える必要が無い */ printf( "行入れ替え %d\n", k ); // 追加 for( j = 0 ; j < NUM ; j++ ){ 列入れ替えが行われているのか確認 /* 3.列入れ換え */ if( k != jmax ){/* 対象としている列と最大値を持つ列が同じなら,入れ替える必要が無い */ printf( "列入れ替え %d\n", k ); // 追加 for( i = 0 ; i < NUM ; i++ ){ ループの終端で変数kが破壊されていないかを確認 } } printf( "ループ %d\n", k ); // 追加 } /* 結果の出力 */ for(i=0; i<NUM; i++){ for(j=0; j<NUM; j++){ といった具合でどこがバグっているのかを確認しましょう
- redfox63
- ベストアンサー率71% (1325/1856)
0 1 4 3 7 0 1 -5 1 3 0 7 -2 4 4 -8 で初回の検索で『-8』が候補に挙がり 0と3行を入れ替え 列の入れ替えはどのようにするのでしょう 入れ替えられた行のa[0][0]とa[0][3]を入れ替えるだけなのか それとも列全体{a[0][0],a[1][0],a[2][0],a[3][0]}と{a[0][3],a[1][3],a[2][3],a[3][3]}を入れ替えるのか ・・・
- redfox63
- ベストアンサー率71% (1325/1856)
列の入れ替えはk行内だけの話ですか? -8.0 4.0 4.0 -2.0 0.0 7.0 1.0 -5.0 1.0 3.0 7.0 0.0 0.0 1.0 3.0 4.0 がこんな感じではないのでしょうか ・・・ 初回のループは16項目中の最大値 2回目は 2行目以降の12個中の最大値 3回目は 3行目以降の8個中の最大値 4回目は 4行目内の最大値 を探すのでしょうか お示しのコードだと 最初は16項目、2回目が a[1][1]からa[3][3]の9個 3回目がa[2][2]からa[3][3]の4個 4回目はa[3][3]のみしか見ていません ・・・ 結果出力の 1つ手前の } 前に 中間結果を k,imax,jmax と共に出力して期待する結果と合致していない部分を探してみましょう
お礼
返信ありがとうございます! >お示しのコードだと 最初は16項目、2回目が a[1][1]からa[3][3]の9個 3回目がa[2][2]からa[3][3]の4個 4回目はa[3][3]のみしか見ていません ・・・ そうなんです。そのように最大値を探すようにつくるようにとかかれておりました。 詳細のせてなくてすみません。
- garaogu
- ベストアンサー率40% (67/166)
こんばんは 列入れ替えのループ内で、配列変数の配列要素を指し示す変数が、jmaxであるべき所を、imaxと間違えているからではないでしょうか? 以下のようにすれば良いのではないでしょうか? /* 3.列入れ換え */ if( k != jmax ){/* 対象としている列と最大値を持つ列が同じなら, 入れ替える必要が無い */ for( i = 0 ; i < NUM ; i++ ){ tmp=a[i][k]; a[i][k]=a[i][jmax]; a[i][jmax]=tmp;/*対象としている列と最大値を持つ列との入れ替え*/ /*ここに列の入れ替え行うプログラムを書く*/ } }
お礼
迅速な回答ありがとうございます! うっかりミスしていました。 確かにそのように変更したところ、確かな表示がでました。 ありがとうございました!
お礼
こんばんわ。 列の入れ替えは、後者の通り入れ替えるようになっています。