[C++] matrici

Messaggioda gazzelle » 16/02/2019, 13:14

Salve a tutti, sono un nuovo utente, volevo chiedere come sostituire la seguente matrice 3x3 con delle variabili libere.
Mi spiego meglio, vorrei che il programma mi chiedesse quante colonne e quante righe vorrei inserire invece di averle già prefissate.
Grazie in anticipo, il programma è il seguente.

Codice:
#include <iostream>
using namespace std;

const int N=3, M=3;

void leggiMatrice(int matrice[N][M]);
void stampaMatrice(int matrice[N][M]);
void calcolaTrasposta(int m[N][M], int t[M][N]);
void calcolaProdotto(int m1[N][M],int m2[M][N], int prodotto[N][N]);

int main(){
    int matrice[N][M], trasposta[M][N], prodotto[N][N];
    leggiMatrice(matrice);
    stampaMatrice(matrice);
    calcolaTrasposta(matrice,trasposta);
    calcolaProdotto(matrice,trasposta,prodotto);

system("PAUSE");
}

void leggiMatrice(int matrice[N][M]){
     cout << "inserisci la matrice " << N << " x " << M << ": " <<endl;
     for (int i=0; i<N; i++)
         for(int j=0; j<M; j++)
             cin >> matrice[i][j];
     return;
}
void stampaMatrice(int matrice[N][M]){
     cout << "La matrice immessa e': " <<endl;
     for (int i=0; i<N; i++){
         for(int j=0; j<M; j++){
             cout << matrice[i][j] << "\t";
         }
         cout <<endl;
     }
     return;
}
void calcolaTrasposta(int m[N][M], int t[M][N]){
     cout << "La matrice trasposta e': " <<endl;
     int temp;
     for (int i=0; i<N; i++){
         for(int j=0; j<M; j++){
             t[j][i]=m[i][j];   //non avevo bisogno di "bloccare" la variabile col temp
         }
     }
     for(int i=0; i<M; i++){
         for(int j=0; j<N; j++){
             cout << t[i][j] << "\t";
         }
         cout <<endl;
     }
     return;
     
}
void calcolaProdotto(int m1[N][M],int m2[M][N], int prodotto[N][N]){
    int k;
    for(int i=0; i<N; i++){
        for(int j=0; j<N; j++){    // il problema era qui.Iinizialmente avevamo j<M, ma la matrice che si viene a formare é NxN, per cui andava sostituito con j<N.
            prodotto[i][j] = 0;
            for(k=0; k<M; k++){   // infine qui, k<M al posto di k<N... ma non ho ben capito.
                prodotto[i][j] += m1[i][k] * m2[k][j];
            }
        }
    }
    cout << "La matrice prodotto delle due e': " <<endl;
    for (int i=0; i<N; i++){
        for(int j=0; j<N; j++){
            cout << prodotto[i][j] << "\t";
        }
        cout <<endl;
    }


    return;
}
gazzelle
Starting Member
Starting Member
 
Messaggio: 1 di 2
Iscritto il: 16/02/2019, 13:06

Re: [C++] matrici

Messaggioda apatriarca » 16/02/2019, 14:55

NOTE: Ti ho modificato il codice in modo da usare il tag code invece di spoiler. In questo modo la formattazione viene preservata.

Sfortunatamente non esiste alcun metodo semplice per farlo. Per passare una matrice bidimensionale come parametro di una funzione il compilatore ha bisogno di conoscere la lunghezza delle righe. Il numero di colonne deve insomma essere costante.

Puoi insomma avere qualcosa come il seguente:
Codice:
void leggiMatrice(int N, int matrice[][M])
{
    // codice che legge la matrice con M costante e N variabile passata come argomento
}


Se questo valore non è costante, è necessario rinunciare agli array multidimensionali e ricorrere a soluzioni alternative.

Queste soluzioni alternative sono:

1. Passare un array monodimensionale e le due dimensioni come argomenti alla funzione. E' forse la soluzione più usata in codici C. Richiede tuttavia di scrivere una formula più complicata per accedere agli elementi.
Codice:
void calcolaTrasposta(int N, int M, int m[], int t[])
{
    for (int i = 0; i < N; ++i) {
        for (int j = 0; j < M; ++j) {
            t[j * N + i] = m[i * M + j];
        }
    }
}


2. Invece di usare un array bidimensionale, è possibile considerare un array di puntatori ad array monodimensionali. Viene insegnato spesso nei corsi scolastici e universitari perché permette di mantenere l'accesso agli elementi come negli array bidimensionali. E' tuttavia necessario allocare e deallocare dinamicamente ogni riga ed è in pratica meno efficiente. Ha principalmente senso se ogni riga ha una lunghezza diversa (per esempio se si vuole rappresentare un testo).

3. In C++ è possibile eliminare le problematiche della prima soluzione usando una classe e facendo l'overload di operatori. Per esempio si può creare qualcosa come segue:
Codice:
class Matrix
{
public:
    Matrix(int N, int M) : _rows(N), _cols(M) { _data = new int[N * M]; }
    ~Matrix() { delete[] _data; }

    int rows() const { return _rows; }
    int cols() const { return _cols; }

    int operator()(int i, int j) const { return _data[i * _cols + j]; }
    int &operator()(int i, int j) { return _data[i * _cols + j]; }

private:
    int _rows, _cols;
    int *_data;
};

Matrix calcolaTrasposta(Matrix m)
{
    Matrix t(m.cols(), m.rows());
    for (int i = 0; i < m.rows(); ++i) {
        for (int j = 0; j < m.cols(); ++j) {
            t(j, i) = m(i, j);
        }
    }
    return t;
}


4. Nel caso in cui la dimensione sia costante e conosciuta durante la compilazione, ma siano necessarie diverse dimensioni in diverse parti del programma, è infine possibile far ricorso a funzioni template.
apatriarca
Moderatore
Moderatore
 
Messaggio: 5196 di 10435
Iscritto il: 08/12/2008, 20:37
Località: Madrid


Torna a Informatica

Chi c’è in linea

Visitano il forum: Nessuno e 1 ospite