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

締切り済みの質問

転置行列と行列の和

初めまして。
大学の授業でプログラミングの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、でやってる人もいるみたいですが具体的な数字で作ろうと思っています。

お手数おかけしますが具体的にお答えいただければ幸いです。
どうぞよろしくお願いいたします。

投稿日時 - 2008-06-08 12:33:26

QNo.4084245

すぐに回答ほしいです

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

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

回答(6)

ANo.6

ヒントだけ。

fscanf( fp, "%lf", &ra[j][i]);

これは何のためにある?

あと、fclose(fp) を適切な場所に入れる必要があります。
これが理解できてないと他の課題をやっても時間の無駄になります。

投稿日時 - 2008-06-09 17:12:12

お礼

完成しました!!
みなさまからたくさんのアドバイスを頂き、
本当に嬉しいです。
以下、完成したプログラムです。
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;
}

投稿日時 - 2008-06-10 15:20:54

ANo.5

ra[] と b[] はdouble 型ですよね。

だったら printf("%d") では正常に出力されません。

printf("%f ") にしなきゃダメ

投稿日時 - 2008-06-09 12:17:36

補足

ありがとうございます!!

ここまでたどり着きましたが
転置行列成功まであと一歩です!!
転置行列の[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;
}

投稿日時 - 2008-06-09 16:38:16

ANo.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;
}

投稿日時 - 2008-06-08 17:20:06

補足

ありがとうございます!!

頑張って作ってみたのが以下ですが、
和の部分が0になってしまいます。

何度も申し訳ありませんが、アドバイスおねがいいたします。



#include <stdio.h>
#include <stdlib.h>

#define ROW3
#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;
}

投稿日時 - 2008-06-09 11:16:25

ANo.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;
}

投稿日時 - 2008-06-08 17:14:45

ANo.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];
を繰り返せばいいでしょう。

投稿日時 - 2008-06-08 13:41:45

補足

ありがとうございます!!
アドバイスを取り入れて修正してみたのですが
これも途中が抜けています。

#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を加えてみました。
これは不要でしょうか?

(まだ行列の和にはたどり着いていない状態です。)

投稿日時 - 2008-06-08 15:05:51

ANo.1

aが2次元配列なのでforループも2重にしないとだめ。

for(i=0; i<ROW; i++){
for( j=0; j< COLUMN ; j++){

という風に。

後は自力でがんばってください。

投稿日時 - 2008-06-08 12:42:10

お礼

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

投稿日時 - 2008-06-08 15:05:25

あなたにオススメの質問