2013-11-20 5 views
0

Я пытаюсь написать код для умножения матриц, общая проблема его в момент, когда «для» cicles пытаются изменить значение результирующей матрицы (C).Матричное умножение ¿логическая ошибка в цикле? (C++ OOP)

Если вы попытаетесь выполнить этот код, введя 2 матрицы A & B, оба 2x2, вы увидите в результатах, что результирующая матрица C показывает только первое значение C [0] [0].

Я уже пытаюсь проверить метод «mult (Matriz A, Matriz B)», но что-то должно быть не так, не могли бы вы помочь мне найти что-то неправильно в cicle.

#include <iostream> 
#include <stdio.h> 

#define TAM 10 

using namespace std; 

class Matriz 
{ 
private: 
    int M[TAM][TAM]; 
    int n, m; 


public: 
    Matriz() 
    { 
     n = m = 1; 
    } 

    Matriz (int n, int m) 
    { 
     this->n = n; 
     this->m = m; 
    } 

    void ingMatriz(char c) 
    { 
     for (int i=0; i<n; i++) 
      for (int j=0; j<m; j++) 
      { 
       cout<<c<<"["<<i+1<<"]["<<j+1<<"]="; 
       cin >>M[i][j]; 
      } 
    } 

    void muestraMatriz() 
    { 
     for (int i=0; i<n; i++) 
     { 
      cout << "\n"; 
      for (int j=0; j<m; j++) 
       cout<<" "<<M[i][j]; 
     } 
    } 

    void mult (Matriz A, Matriz B) 
    { 
     int an=A.n; 
     int am=A.m; 
     int bm=B.m; 


     for(int a=0; a<an; a++) //This is the general cicle 
      for(int b=0; b<bm; b++) 
       for(int c=0; c<am; c++) 
        M[a][b] += (A.M[a][c] * B.M[c][b]); 
    } 

}; 

int main() 
{ 
    cout << "\nxxxxxx Multiplicacion de matrices xxxxxx"; 

    int f1,c1,f2,c2; 

    cout<< "\n \n* El numero de columnas de la 1er matriz(A) debe ser igual a numero de filas de la segunda matriz(B) *"; 
    cout<< "\n \nIngresa el numero de FILAS de la 1er matriz(A): "; 
    cin >> f1; 
    cout<< "\nIngresa el numero de COLUMNAS de la 1er matriz(A): "; 
    cin >> c1; 
    cout<< "\nIngresa el numero de FILAS de la 2da matriz(B): "; 
    cin >> f2; 
    cout<< "\nIngresa el numero de COLUMNAS de la 2da matriz(B): "; 
    cin >> c2; 

    if (c1==f2) 
    { 
     Matriz A(f1,c1); 
     cout << "\nIngresa los valores de la matriz 'A': \n\n"; 
     A.ingMatriz('A'); 
     Matriz B(f1,c2); 
     cout << "\n \n********************************************\nIngresa los valores de la matriz 'B': \n \n"; 
     B.ingMatriz('B'); 

     Matriz C; 
     C.mult(A,B); 
     cout << "\nMatriz A: "; 
     A.muestraMatriz(); 
     cout << "\nMatriz B: "; 
     B.muestraMatriz(); 
     cout << "\nMultiplicacion AB: "; 
     C.muestraMatriz(); 
    } 
    else 
     cout << "\n \n \n El numero de columnas de la 1er matriz(A) debe ser igual al numero de filas de la segunda matriz(B) "; 

    getchar(); 
    getchar(); 
    return 0; 
}; 

я изменил всего несколько вещей, в основном, как вы можете видеть на картинке, я изменил объект C, чтобы Matriz C (f1, c2), поэтому он может установить значения для результирующей матрицы, но все еще показывает мусор. Heres картина выхода:

http://i.stack.imgur.com/oTdK7.png

FINAL КОД:

#include <iostream> 
#include <stdio.h> 
#include <cstdlib> 
#define TAM 10 

using namespace std; 

class Matriz 
{ 
     private: 
       int M[TAM][TAM]; 
       int n, m; 
     public: 
      Matriz():n(1), m(1) 
      { 
       for (int i=0; i<TAM; i++) 
       for (int j=0; j<TAM; j++) 
       M[i][j] = 0; 
      } 

      Matriz (int n, int m):n(n), m(m) 
      { 
       for (int i=0; i<TAM; i++) 
       for (int j=0; j<TAM; j++) 
       M[i][j] = 0; 
      } 
      void ingMatriz(char c) 
      { 
       for (int i=0; i<n; i++) 
        for (int j=0; j<m; j++) 
        { 
         cout<<c<<"["<<i+1<<"]["<<j+1<<"]="; 
         cin >> M[i][j]; 
        } 
      } 

      void muestraMatriz() 
      { 
       for (int i=0; i<n; i++) 
       { 
        cout << "\n"; 
        for (int j=0; j<m; j++) 
        cout<<" "<<M[i][j]; 
       } 
      } 

      void mult (Matriz A, Matriz B) 
      { 
        int an=A.n; 
        int am=A.m; 
        int bm=B.m; 

       for(int a=0; a<an; a++) 
        for(int b=0; b<bm; b++) 
         for(int c=0; c<am; c++)          
          M[a][b] += (A.M[a][c] * B.M[c][b]);    
       } 
}; 

int main() 
{ 
    while (0<1){ 
    cout << "xxxxxx Multiplicacion de matrices xxxxxx"; 
    int f1,c1,f2,c2; 

    cout<< "\n \n* El numero de columnas de la 1er matriz(A) debe ser igual al numero de filas de la segunda matriz(B) *"; 

    cout<< "\n \nIngresa el numero de FILAS de la 1er matriz(A): "; 
    cin >> f1; 

    cout<< "\nIngresa el numero de COLUMNAS de la 1er matriz(A): "; 
    cin >> c1; 

    cout<< "\nIngresa el numero de FILAS de la 2da matriz(B): "; 
    cin >> f2; 

    cout<< "\nIngresa el numero de COLUMNAS de la 2da matriz(B): "; 
    cin >> c2; 

    if (c1==f2) 
    { 
    Matriz A(f1,c1);  
    cout << "\nIngresa los valores de la matriz 'A': \n\n"; 
    A.ingMatriz('A'); 
    Matriz B(f2,c2); 

cout << "\n \n********************************************\nIngresa los valores de la matriz 'B': \n \n"; 
B.ingMatriz('B'); 
Matriz C(f1,c2); 
C.mult(A,B); 
cout << "\n\nMatriz A: "; 
A.muestraMatriz(); 
cout << "\n\nMatriz B: "; 
B.muestraMatriz(); 
cout << "\n\nMultiplicacion AB: "; 
C.muestraMatriz(); 
} 
else 
cout << "\n \n \n El numero de columnas de la 1er matriz(A) debe ser igual al numero de filas de la segunda matriz(B) "; 
getchar(); 
getchar(); 
system("cls"); 
} 
return 0; 
}; 
+0

Я думаю, это потому, что вы никогда не ставили н и м для «это» результирующая матрица – alexbuisson

+0

Ммма, я попытался изменить Matriz C (f1, c2); C.mult (A, B); f1 = общая сумма строк c2 = совокупность колонок матрицы B Теперь она отображает всю результирующую матрицу, но содержимое все еще является мусором. f1 = строки матрицы – MrcRjs

+0

Можете ли вы опубликовать вывод также? – Thanushan

ответ

1

Это немного сложно для меня, чтобы сказать, что ваша основная функция делает, потому что я не родной испанский динамик =)

Но проблема заключается в том, что вы инициализируете C, используя конструктор по умолчанию, который инициализирует его ширину и высоту как один. Затем, когда вы пытаетесь умножить две другие матрицы 2 * 2, индексы, которые вы умножаете, никогда не превышают 1 и 1, даже если A и B имеют n = 2 и m = 2, так как C имеет только n = m = 1 (как указано в его конструкторе) он только умножает первый элемент, а затем выходит из обеих петель.

Для того, чтобы получить то, что вы хотите, вы должны инициализировать C до соответствующих размеров первой, как так:

Matriz C(2, 2)

Однако, это может раздражать довольно быстро, так как вы уже знаете, что выход размер матрицы должен быть - поэтому в коде умножения матрицы вы можете установить m = A.m и n = B.n соответственно, так как результирующая матрица умножения должна иметь ширину 1-й матрицы и высоту 2-го. Тогда вам просто нужно убедиться, что вы переходите в матрицы нужного размера при умножении =)

Вторая проблема, которую я вижу, заключается в том, что вы не инициализируете значения C ни к чему, прежде чем выполнять умножение сущность, которую вы делаете умножением правильно, но так как вы уже неинициализировали значения, когда вы добавляете умножение, мусор + x = больше мусора. EDIT: случайный пост до этого. Вы хотите изменить строку M[a][b] += (A.M[a][c] * B.M[c][b]); на M[a][b] = (A.M[a][c] * B.M[c][b]); - таким образом вы правильно установите значение в соответствие с тем, что должно быть, вместо добавления к тому, что уже было там.

EDIT2: вместо инициализации в самом коде умножения (см комментариев) вы должны инициализировать в конструкторах с петлей:

public: 
    Matriz():n(1), m(1) //also note the initializer lists instead of doing it in the body of the ctor 
    { 
     for (int i = 0; i < TAM; ++i) 
      for (int j = 0; i < TAM; ++j) 
       M[i][j] = 0; 
    } 

    Matriz (int n, int m):n(n), m(m) //lets you do this instead of explicitly dereferencing this (this->n = n, etc) -- 
            //also, more efficient generally (though maybe not since your data is only ints in this case anyways) 

    { 
     for (int i = 0; i < TAM; ++i) 
      for (int j = 0; i < TAM; ++j) 
       M[i][j] = 0; 
    } 
+0

Я сделал это, пожалуйста, проверьте сообщение, я добавил новую информацию и вывод. Спасибо – MrcRjs

+0

Ну, вторая проблема, которую я вижу, заключается в том, что вы не инициализируете значения C ни к чему, прежде чем выполнять умножение - по сути, вы делаете умножение правильно, но поскольку у вас уже есть неинициализированные значения, когда вы добавляете умножение на, мусор + x = больше мусора. EDIT: случайный post перед тем как сделать. Вы хотите изменить строку 'M [a] [b] + = (AM [a] [c] * BM [c] [b]);' to 'M [a] [b] = (AM [ a] [c] * BM [c] [b]); '- таким образом вы правильно установите значение в том, что должно быть, вместо того, чтобы добавлять к тому, что уже было там. –

+0

Отредактированный мой ответ включить это;) –

0

Поскольку вы перемножением 2 матрицы: A.n = B.м, так что ваш код должен быть больше похоже:

void mult (Matriz A, Matriz B) 
    { 
    for(k=0;k<A.m;k++) 
    { 
     for(i=0;i<A.n;i++) 
     { 
     M[i][k] = 0; 
     for(j=0;j<B.m;j++) 
      M[k][i] += A[k][j] * B[j][i] 
     cout << "Matriz c:" << M[k][i]<<" ";  
     } 
     cout <<"\n"; 
     } 
Смежные вопросы