2016-05-03 5 views
1

В качестве упражнения я должен написать функцию, которая может умножать две матрицы, заданные для определенного ввода. То, как упражнение пишется функция должна иметь вид:Запись функции для умножения матриц в C++

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

Если результат умножения записывается в разрешении. Я не уверен, что понимаю вышеприведенную форму. Насколько я понимаю, в качестве входных данных принимаются адреса двух матриц и числа их столбцов и строк. Но каков должен быть вход res (который является результатом умножения матриц)? Должен ли он быть адресом предварительно распределенной матрицы с правильными размерами? В этом случае я написал следующее, чтобы проверить функцию (я также указана матрица А и В):

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]; 
      } 
     } 
    } 
} 

Тест на Multiply:

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

Выполнение &C, &A, &B даст адрес, что указатель двойной указатель хранится в. Это означало бы, что Multiply будет принимать double***: указатель на тип double**. Вы можете просто передать его как

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

, который будет проходить три double** типа, а именно A, B и C.

Также неверен способ использования new. Вам необходимо использовать

C = new double*[rows]; 

Вы также пытаетесь напечатать функцию void, которая не сработает. Умножение - это не то, что вы можете распечатать, вам нужно назвать его так, чтобы определить 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

Я попытался определить Multiply ниже, но я не уверен, как мне следует называть A и B. Поскольку они теперь являются двойными указателями, я могу просто написать A [i] [j] или написать I ** A [i] [j ]? При попытке компиляции я получаю некоторые странные ошибки. Я включил свой код для Multiply в OP. – user13514

+0

Необходимо использовать C = новый double * [rows]; – mojo1mojo2

Смежные вопросы