ここから本文です

c言語で、1次元配列で行列を表した場合なんですが、次の関数でなぜ、行列の行数と...

kop********さん

2013/7/2813:49:41

c言語で、1次元配列で行列を表した場合なんですが、次の関数でなぜ、行列の行数と行数を入れ替えられるのか分かりません。教えていただけませんか?

また、ある行に係数をかける場合、どのようなコードになるか、以下の関数のような感じで書きたいのですが、教えて頂けませんか?お願いします。

関数
void exchange_matrix_row(double mat,int n,int s,int t) /*s,tは行を表す*/
{
int j;
double tmp;
if(s==t)
{
return ;
}
for(j=0;j<n+1;j++){
tmp=mat[s*(n+1)+j];
mat[s*(n+j)]=mat[t*(n+1)+j];
mat[t*(n+1)+j]=tmp;
}
return ;
}

補足すいません、1行目の質問文で、「行数と行数を入れ替える」ではなく、「行と行を入れ替える」でした。訂正します。

閲覧数:
1,159
回答数:
3
お礼:
50枚

違反報告

ベストアンサーに選ばれた回答

gan********さん

2013/7/3021:30:32

例えば、

*__0__1__2__3
0_11__12_13_14
1_21 _22_23_24
2_31_ 32_33_34

のような二次元配列があった場合、一次元配列mat (要素の型は都合上intですが同じです)で表すと、

***__0__1__2__3__4__5__6__7__8__9_10_11
mat_11_12_13_14_21_22_23_24_31_32_33_34

のようになります。

関数の中身で大事なのは、二次元の行列と一次元配列の対応です。
各行の先頭は、一次元配列で、0,4,8の位置にあります。
つまり、4*C (C = 0,1,2, ...: 行番号)で、4は列数です。
一般化すれば、列数をRとすれば、 R*C、
一次元配列のこの位置に二次元配列の行の最初の要素がある訳です。

二次元の行列の行の先頭要素が一次元配列のどこにあるのかが求まったので、
その行の他の要素にアクセスするには、[先頭要素の位置] + [j] (j=0,1,2,...,R-1)で行えます。
for分の中身は、典型的な入れ替えです(書き間違えだと思いますが)。

次に、ある行に係数をかける場合ですが、
必要なのは、配列と、特定の行と列数と、係数です。

関数定義は次のようになり、

void gyo_ni_keisu(double*mat, int r, int c, int k)
/* mat:配列, r:列数, c:行番号 ,k:係数 */

中身は、先頭から列数分、forで回して掛ければいいでしょう。

void gyo_ni_keisu(double*mat, int r, int c, double k){
int i;
int i0 = r*c;

for (i = 0; i < r; i++){
mat[i0 + i] = mat[i0 + i] * k;
}

}

質問した人からのコメント

2013/7/31 00:57:56

ありがとうございます。参考にさせていただきます。

ベストアンサー以外の回答

1〜2件/2件中

並び替え:回答日時の
新しい順
|古い順

azu********さん

2013/7/2823:19:45

/*
デバッグ用のルーチンも付け加えてみました。
行数 R、列数 C の値をいろいろ変えて確認してみてください。

引数の形を変えるとまた違った処理になります。
//■ のついている行を対応する次の行に置き換えても入れ替えができます

---------------------------------------
void exchange_matrix_row( double mat[],int n,int s,int t) // s,tは行番号、n は行の要素数 //■
void exchange_matrix_row( double (*mat)[C],iint s,int t) // s,tは行番号、

for(j=0; j<n; j++){//■
tmp = mat[n*s+j];//■
mat[n*s+j] = mat[n*t+j];//■
mat[n*t+j] = tmp;//■
}//■

for(j=0;j<n;j++){
tmp=*(mat[s]+j);
*(mat[s]+j)=*(mat[t]+j);
*(mat[t]+j)=tmp;
}

exchange_matrix_row(&(matrix[0][0]), C, s-1, t-1);//■
exchange_matrix_row(matrix, s-1, t-1);
-----------------------------------------
*/

#define R 5 //行数
#define C 3 //列数
#include <stdio.h>


void exchange_matrix_row( double *mat,int n,int s,int t) // s,tは行番号、n は行の要素数 //■
// void exchange_matrix_row( double mat[],int n,int s,int t) // これでも可
{
int i,j;
double tmp;
if(s==t) return;

for(j=0; j<n; j++){//■
tmp = mat[n*s+j];//■
mat[n*s+j] = mat[n*t+j];//■
mat[n*t+j] = tmp;//■
}//■
// return; // 関数の最後の } の直前の return; は省略できる
}


void disp_matrix(double (*matrix)[C])
{
int i, j;

for(i=0; i<R; i++){
printf("%d : ", i+1);
for(j=0; j<C; j++)
printf("%5.1f", matrix[i][j]);
puts("");
}
puts("");
}


int main(void)
{
double matrix[R][C];
int i, j, s, t;

for(i=0; i<R; i++)
for(j=0; j<C; j++)
matrix[i][j] = C*i+j;

puts("\n交換前");
disp_matrix(matrix);

do{
printf("何行と何行を入れ替えますか (スペースで区切って入力):");
scanf("%d %d", &s, &t);
} while( !((1<=s && s <=R)&&(1<=t && t <=R)) );


exchange_matrix_row((double *)matrix, C, s-1, t-1);//■
// exchange_matrix_row(&matrix[0][0], C, s-1, t-1); でも可
puts("\n交換後");
disp_matrix(matrix);

return 0;
}
/*
■実行例

交換前
1 : 0.0 1.0 2.0
2 : 3.0 4.0 5.0
3 : 6.0 7.0 8.0
4 : 9.0 10.0 11.0
5 : 12.0 13.0 14.0

何行と何行を入れ替えますか (スペースで区切って入力):1 6
何行と何行を入れ替えますか (スペースで区切って入力):1 5

交換後
1 : 12.0 13.0 14.0
2 : 3.0 4.0 5.0
3 : 6.0 7.0 8.0
4 : 9.0 10.0 11.0
5 : 0.0 1.0 2.0

*/

2013/7/2815:49:15

mat

の型は

doubleで合ってますか?

double*型のような気がしますが?

あわせて知りたい

この質問につけられたタグ

みんなで作る知恵袋 悩みや疑問、なんでも気軽にきいちゃおう!

Q&Aをキーワードで検索:

Yahoo! JAPANは、回答に記載された内容の信ぴょう性、正確性を保証しておりません。
お客様自身の責任と判断で、ご利用ください。
本文はここまでです このページの先頭へ

「追加する」ボタンを押してください。

閉じる

※知恵コレクションに追加された質問は選択されたID/ニックネームのMy知恵袋で確認できます。

不適切な投稿でないことを報告しました。

閉じる