• 締切済み

転置行列と行列の和

初めまして。 大学の授業でプログラミングのC言語を勉強しています。 4月からプログラミングを始めたばかりで、まったくの初心者です。 転置行列が作れなくて困っているのですが、 .datのファイルから転置させるのが上手くできません。 《kadai1.datの3行4列の行列Aと、kadai2.datの4行3列行列Bがある。 行列A、行列B、行列Aの転置行列を出力し、 行列Aの転置行列と行列Bの和を出力するプログラムを作る。 kadai1.datとkadai2.datは自分で作る。》 で、途中まで作ったのが以下です。 #include <stdio.h> #include <stdlib.h> #define ROW   3 #define COLUMN 4 int main(void) { FILE *fp; double a[ROW][COLUMN], b[ROW][COLUMN]; int i, j; if ( ( fp = fopen( "kadai1.dat", "r" ) ) == NULL ) { printf("ファイルが見つかりません : kadai1.dat \n"); exit(1); } printf("行列Aは次の通りです\n"); for ( i = 0 ; j < COLUMN ; j++) { scanf (fp, "%lf", &a[i][j]); printf ("%5.2f\t", a[i][j]); } printf("\n"); } if ( ( fp = fopen( "kadai2.dat", "r" ) ) == NULL ) { printf("ファイルが見つかりません : kadai2.dat \n"); exit(1); } printf("行列Bは次の通りです\n"); for ( i = 0 ; j < COLUMN ; j++) { scanf (fp, "%lf", &a[i][j]); printf ("%5.2f\t", a[i][j]); } printf("\n"); } return 0; } \の半角が出なかったので¥になってます。 (ごめんなさい!!) 上のプログラムで、行列Aと行列Bが出力できたのですが、転置と和のプログラムが出来ていません。 kadai1.datが、 1 2 3 4 5 6 7 8 9 10 11 12 kadai2.datが、 13 14 15 16 17 18 19 20 21 22 23 24 にしてみました。a1 a2 … c3 c4、でやってる人もいるみたいですが具体的な数字で作ろうと思っています。 お手数おかけしますが具体的にお答えいただければ幸いです。 どうぞよろしくお願いいたします。

みんなの回答

回答No.6

ヒントだけ。 fscanf( fp, "%lf", &ra[j][i]); これは何のためにある? あと、fclose(fp) を適切な場所に入れる必要があります。 これが理解できてないと他の課題をやっても時間の無駄になります。

noname#61072
質問者

お礼

完成しました!! みなさまからたくさんのアドバイスを頂き、 本当に嬉しいです。 以下、完成したプログラムです。 kadai2.datを 13 17 21 14 18 22 15 19 23 16 20 24 に変更しました。 #include <stdio.h> #include <stdlib.h> #define ROW 3 #define COLUMN 4 int main(void) { FILE *fp; double a[ROW][COLUMN], b[ROW][COLUMN]; double ra[COLUMN][ROW], c[COLUMN][ROW]; int i, j, r; if ( ( fp = fopen( "kadai1.dat", "r" ) ) == NULL ) { printf("ファイルが見つかりません : kadai1.dat \n"); exit(1); } printf("行列Aは次の通りです\n"); for(i=0; i<ROW; i++) { for( j=0; j< COLUMN ; j++) { fscanf (fp, "%lf", &a[i][j]); printf ("%5.2f\t", a[i][j]); ra[j][i]= a[i][j]; } printf("\n"); } printf("行列Aの転置行列を求めると\n"); for(j=0;j < COLUMN ; j++) { for(i = 0; i < ROW; i++) { fscanf( fp, "%lf", &ra[j][i]); printf( "%5.2f\t", ra[j][i]); } printf("\n"); } if ( ( fp = fopen( "kadai2.dat", "r" ) ) == NULL ) { printf("ファイルが見つかりません : kadai2.dat \n"); exit(1); } printf("行列Bは次の通りです\n"); for(i=0; i<COLUMN; i++) { for( j=0; j<ROW ; j++) { fscanf (fp, "%lf", &b[i][j]); printf ("%5.2f\t", b[i][j]); } printf("\n"); } printf("行列Aの転置行列と行列Bとの和は\n"); for (i = 0; i < COLUMN; i++) { for (j = 0; j < ROW; j++) { c[i][j] = ra[j][i] + b[i][j]; printf("%lf", c[i][j]); } printf("\n"); } printf("\n"); fclose(fp); return 0; }

回答No.5

ra[] と b[] はdouble 型ですよね。 だったら printf("%d") では正常に出力されません。 printf("%f ") にしなきゃダメ

noname#61072
質問者

補足

ありがとうございます!! ここまでたどり着きましたが 転置行列成功まであと一歩です!! 転置行列の[i][j]やROW、COLUMNのところで間違いがあるのでしょうか? #include <stdio.h> #include <stdlib.h> #define ROW 3 #define COLUMN 4 int main(void) { FILE *fp; double a[ROW][COLUMN], b[ROW][COLUMN]; double ra[COLUMN][ROW], c[COLUMN][ROW]; int i, j, r; if ( ( fp = fopen( "kadai1.dat", "r" ) ) == NULL ) { printf("ファイルが見つかりません : kadai1.dat \n"); exit(1); } printf("行列Aは次の通りです\n"); for(i=0; i<ROW; i++) { for( j=0; j< COLUMN ; j++) { fscanf (fp, "%lf", &a[i][j]); printf ("%5.2f\t", a[i][j]); ra[j][i]= a[i][j]; } printf("\n"); } printf("行列Aの転置行列を求めると\n"); for(i=0;i < COLUMN ; i++) { for(j = 0; j < ROW; j++) { fscanf( fp, "%lf", &ra[j][i]); printf( "%5.2f\t", ra[j][i]); } printf("\n"); } if ( ( fp = fopen( "kadai2.dat", "r" ) ) == NULL ) { printf("ファイルが見つかりません : kadai2.dat \n"); exit(1); } printf("行列Bは次の通りです\n"); for(i=0; i<COLUMN; i++) { for( j=0; j<ROW ; j++) { fscanf (fp, "%lf", &b[i][j]); printf ("%5.2f\t", b[i][j]); } printf("\n"); } printf("行列Aの転置行列と行列Bとの和は\n"); for (i = 0; i < COLUMN; i++) { for (j = 0; j < ROW; j++) { c[i][j] = ra[j][i] + b[i][j]; printf("%lf", c[i][j]); } printf("\n"); } printf("\n"); return 0; }

  • asuncion
  • ベストアンサー率33% (2127/6290)
回答No.4

おっと失礼。 #include <stdio.h> #include <stdlib.h> #define X (3) #define Y (4) int main(void) { int a[X][Y], ra[Y][X], b[Y][X], i, j; FILE *fpa, *fpb; fpa = fopen("kadai1.dat", "r"); if (fpa == NULL) { fprintf(stderr, "kadai1.datがオープンできません。\n"); exit(1); } printf("【行列A】\n"); for (i = 0; i < X; i++) { for (j = 0; j < Y; j++) { fscanf(fpa, "%d", &a[i][j]); printf("%d ", a[i][j]); ra[j][i] = a[i][j]; } putchar('\n'); } putchar('\n'); fclose(fpa); fpb = fopen("kadai2.dat", "r"); if (fpb == NULL) { fprintf(stderr, "kadai2.datがオープンできません。\n"); exit(1); } printf("【行列B】\n"); for (i = 0; i < Y; i++) { for (j = 0; j < X; j++) { fscanf(fpb, "%d", &b[i][j]); printf("%d ", b[i][j]); } putchar('\n'); } putchar('\n'); fclose(fpb); printf("【行列Aの転置行列と行列Bとの和】\n"); for (i = 0; i < Y; i++) { for (j = 0; j < X; j++) { printf("%d ", ra[i][j] + b[i][j]); } putchar('\n'); } putchar('\n'); return 0; }

noname#61072
質問者

補足

ありがとうございます!! 頑張って作ってみたのが以下ですが、 和の部分が0になってしまいます。 何度も申し訳ありませんが、アドバイスおねがいいたします。 #include <stdio.h> #include <stdlib.h> #define ROW 3 #define COLUMN 4 int main(void) { FILE *fp; double a[ROW][COLUMN], b[ROW][COLUMN]; double ra[COLUMN][ROW]; int i, j, c, r; if ( ( fp = fopen( "kadai1.dat", "r" ) ) == NULL ) { printf("ファイルが見つかりません : kadai1.dat \n"); exit(1); } printf("行列Aは次の通りです\n"); for(i=0; i<ROW; i++) { for( j=0; j< COLUMN ; j++) { fscanf (fp, "%lf", &a[i][j]); printf ("%5.2f\t", a[i][j]); ra[j][i]= a[i][j]; } printf("\n"); } if ( ( fp = fopen( "kadai1.dat", "r" ) ) == NULL ) { printf("ファイルが見つかりません : kadai1.dat \n"); exit(1); } printf("行列Aの転置行列を求めると\n"); for(i=0;i < COLUMN ; i++) { for(j = 0; j < ROW; j++) { fscanf( fp, "%lf", &ra[j][i]); printf( "%5.2f\t", ra[j][i]); } printf("\n"); } if ( ( fp = fopen( "kadai2.dat", "r" ) ) == NULL ) { printf("ファイルが見つかりません : kadai2.dat \n"); exit(1); } printf("行列Bは次の通りです\n"); for(i=0; i<COLUMN; i++) { for( j=0; j<ROW ; j++) { fscanf (fp, "%lf", &b[i][j]); printf ("%5.2f\t", b[i][j]); } printf("\n"); } printf("行列Aの転置行列と行列Bとの和は\n"); for (i = 0; i < COLUMN; i++) { for (j = 0; j < ROW; j++) { printf("%d ", ra[j][i] + b[i][j]); } printf("\n"); } printf("\n"); return 0; }

  • asuncion
  • ベストアンサー率33% (2127/6290)
回答No.3

#include <stdio.h> #include <stdlib.h> #define X (3) #define Y (4) int main(void) { int a[X][Y], ra[Y][X], b[Y][X], i, j; FILE *fpa, *fpb; fpa = fopen("kadai1.dat", "r"); if (fpa == NULL) { fprintf(stderr, "kadai1.datがオープンできません。\n"); exit(1); } for (i = 0; i < X; i++) { for (j = 0; j < Y; j++) { fscanf(fpa, "%d", &a[i][j]); ra[j][i] = a[i][j]; } } fclose(fpa); fpb = fopen("kadai2.dat", "r"); if (fpb == NULL) { fprintf(stderr, "kadai2.datがオープンできません。\n"); exit(1); } for (i = 0; i < Y; i++) { for (j = 0; j < X; j++) { fscanf(fpb, "%d", &b[i][j]); printf("%d ", ra[i][j] + b[i][j]); } putchar('\n'); } fclose(fpb); return 0; }

回答No.2

転置行列を作るんだから double a[ROW][COLUMN], b[ROW][COLUMN]; に加えて double ra[COLUMN][ROW], rb[COLUMN][ROW]; を用意し、aからra / bからrb に要素を転記するんでしょうね。 r,cをころころ変えながら ra[c][r] = a[r][c]; rb[c][r] = b[r][c]; を繰り返せばいいでしょう。

noname#61072
質問者

補足

ありがとうございます!! アドバイスを取り入れて修正してみたのですが これも途中が抜けています。 #include <stdio.h> #include <stdlib.h> #define ROW   3 #define COLUMN 4 int main(void) { FILE *fp; double a[ROW][COLUMN], b[ROW][COLUMN]; double ra[COLUMN][ROW], rb[COLUMN][ROW];   int i, j, c, r; if ( ( fp = fopen( "kadai1.dat", "r" ) ) == NULL ) { printf("ファイルが見つかりません : kadai1.dat \n"); exit(1); } printf("行列Aは次の通りです\n"); for(i=0; i<ROW; i++) { for( j=0; j< COLUMN ; j++) { fscanf (fp, "%lf", &a[i][j]); printf ("%5.2f\t", a[i][j]); } printf("\n"); } if ( ( fp = fopen( "kadai2.dat", "r" ) ) == NULL ) { printf("ファイルが見つかりません : kadai2.dat \n"); exit(1); }   printf("行列Bは次の通りです\n");   for(i=0; i<ROW; i++) { for( j=0; j< COLUMN ; j++) { scanf (fp, "%lf", &a[i][j]);   printf ("%5.2f\t", a[i][j]); } printf("\n"); } printf("行列Aの転置行列を求めると\n"); for(i=0;i<ROW;i++) { for(j=0;j<COLUMN ; j++) { ra[c][r] = a[r][c]; rb[c][r] = b[r][c]; } printf("\n"); }      return 0; }          *********** もうすこし教えて頂きたいのですが、  ra[c][r] = a[r][c];   rb[c][r] = b[r][c]; の部分はscanf(…) の中に入れれば良かったのでしょうか? また、上の方のintにrとcを加えてみました。 これは不要でしょうか? (まだ行列の和にはたどり着いていない状態です。)

回答No.1

aが2次元配列なのでforループも2重にしないとだめ。 for(i=0; i<ROW; i++){ for( j=0; j< COLUMN ; j++){ という風に。 後は自力でがんばってください。

noname#61072
質問者

お礼

ありがとうございます!! 致命的なミスでした。 2番目に答えてくれた方の補足欄に 修正してみたプログラムを載せました。

関連するQ&A