2016-05-03 5 views
1

練習として、ある入力を指定すると2つの行列を掛ける関数を書くことになっています。運動機能を書かれている方法は、次の形式になります乗算の結果がRESに書き込まれC++で行列を掛ける関数を書く

void Multiply(double **res, double **A, double **B, int ARows, int ACols, int BRows, int BCols);   

。 上記のフォームがわかりません。私が理解できる限り、2つの行列のアドレスとその列と行の数を入力として取ります。しかし、resの入力はどのようにすべきですか(行列を乗算した結果です)?あらかじめ割り当てられた行列のアドレスが正しい次元でなければなりませんか?その場合、私は関数をテストするために次のように書いた(私は行列AとBも指定した)。

double** C; 
C = new double [rows]; 
for (int i=0; i<rows; i++) 
{ 
C[i] = new double [cols]; 
} 
std::cout << Multiply(&C,&A,&B,Arows,Acols,Brows,Bcols) << "\n"; 
} 

しかし、私は正しいとは思わない。ここでは乗算のための私のコードされる:乗算のための

void Multiply(double **res, double **A, double **B, int ARows, int  ACols, int BRows, int BCols) 
{ 
    assert(ACols=BRows); 
    for (int k=0; k<BCols; k++) 
    { 
     for (int j=0; j<ARows; j++) 
     { 
      for (int i=0; i<ACols; i++) 
      { 
       res[j][k] += A[j][i]*B[i][k]; 
      } 
     } 
    } 
} 

テスト:&C, &A, &Bを行う

int main() 
{ 
    int ARows = 2; 
    int ACols = 3; 
    int BRows = 3; 
    int BCols = 2; 
    int cols = ARows; 
    int rows = BCols; 
    double** A; 
    A = new double* [ARows]; 
    for (int i=0; i<ARows; i++) 
    { 
     A[i] = new double [ACols]; 
    } 
    double** B; 
    B = new double* [BRows]; 
    for (int i=0; i<BRows; i++) 
    { 
     B[i] = new double [BCols]; 
    } 
    A[0][0]=1; 
    A[0][1]=2; 
    A[0][2]=3; 
    A[1][0]=4; 
    A[1][1]=6; 
    A[1][2]=10; 
    B[0][0]=1; 
    B[0][1]=2; 
    B[1][0]=4; 
    B[1][1]=6; 
    B[2][0]=13; 
    B[2][1]=9; 
    double** C; 
    C = new double* [rows]; 
    for (int i=0; i<rows; i++) 
    { 
     C[i] = new double [cols]; 
    } 
    std::cout << Multiply(C,A,B,ARows,ACols,BRows,BCols) << "\n"; 
} 
+1

乗算はres' 'は' 'ダブル**を期待し、 'C'はすでに' 'ダブル**であるとして、関数に渡す'&C'する必要はありません。とプレーンな 'C'を渡すだけで十分です。さらに、すでにポインタであるため、関数は指摘されたコンテンツを埋めることができます。 –

答えて

2

は、ダブルポインタのポインタが格納されていることでアドレスを与えます。これは、Multiplydouble***double**タイプへのポインタを取ることを意味します。 3つのdouble**種類、すなわちAB、およびCを渡しますどの

std::cout << Multiply(C,A,B,Arows,Acols,Brows,Bcols) << "\n"; 

としてあなたはそれを渡すことができます。

また、newをCに使用する方法は間違っています。あなたは使用する必要があります

C = new double*[rows]; 

あなたはまた、動作しないボイド関数を印刷しようとしています。乗算は印刷できるものではなく、Cが定義されるように呼び出す必要があります。次に、ループスルーしてCを手動で出力する必要があります。私は以下のコードを書いています。

#include <iostream> 

void Multiply(double **res, double **A, double **B, int aRows, int aCols, int bRows, int bCols) 
{ 
    if (aCols != bRows) 
     return; 

    for (int i = 0; i < aRows; i++) 
    { 
     for (int j = 0; j < bCols; j++) 
     { 
      res[i][j] = 0; 
      for (int k = 0; k < aCols; k++) 
      { 
       res[i][j] += A[i][k]*B[k][j]; 
      } 
     } 
    } 
} 

void Initialise(double **res, int rows, int cols) 
{ 
    for (int i = 0; i < rows; i++) 
    { 
     for(int j = 0; j < cols; j++) 
     { 
      res[i][j] = i*j; // whatever you want. 
     } 
    } 
} 

int main() 
{ 
    int aRows = 10; 
    int aCols = 5; 
    int bRows = 5; 
    int bCols = 6; 

    double** A = new double*[aRows]; 
    for (int i = 0; i < aRows; i++) 
    { 
     A[i] = new double[aCols]; 
    } 

    double** B = new double*[bRows]; 
    for (int i = 0; i < bRows; i++) 
    { 
     B[i] = new double[bCols]; 
    } 

    Initialise(A, aRows, aCols); 
    Initialise(B, bRows, bCols); 

    double** C; 
    C = new double*[aRows]; 
    for (int i = 0; i < aRows; i++) 
    { 
     C[i] = new double [bCols]; 
    } 

    Multiply(C,A,B,aRows,aCols,bRows,bCols); 

    for (int i = 0; i < aRows; i++) 
    { 
     for (int j = 0; j < bCols; j++) 
     { 
      std::cout << C[i][j] << ' '; 
     } 
     std::cout << '\n'; 
    } 

    return 0; 
} 
+0

これらはダイナミックメモリを使用しているので、参照渡しの必要はありません。 – mojo1mojo2

+0

私は以下に掛け算を定義しようとしましたが、AとBをどのように呼び出すべきかわかりません。現在は二重ポインタなのでA [i] [j]を書くことができますか? ]?コンパイルしようとすると奇妙なエラーが出ます。 OPにMultiplyのコードを追加しました。 – user13514

+0

C = new double * [行]を使用する必要があります。 – mojo1mojo2