[C] Costruzione matrice

Mrhaha
Ciao ragazzi, c'era un esercizio che stavo facendo,riguardava esattamente la creazione di un programma in C per la costruzione di una matrice il cui elemento $M(i,j)$ sarà $i!+j!$. Ne ho fatti alcuni,ma uno non mi viene,e sinceramente non capisco dove stia sbagliando!
Qualcuno mi può spiegare dove sbaglio?
#include <stdio.h>
#include <stdlib.h>

int main(void) {
     int **m,i,j,N,M,k,fatt,n;
     printf ("Inserire numero righe\n");
     scanf("%d",&N);
     printf("Inserire numero colonne");
     scanf("%d",&M);
     m=(int**)malloc(sizeof(int)*N);
     for(i=0;i<N;i++){
                      m[i]=(int*)malloc(sizeof(int)*M);
                      }
     for(i=0;i<N;i++){
                      for(j=0;j<M;j++){
                                       n=i;
                                       fatt=1;
                                       for( ;n>1;n--){
                                            fatt*=n;
                                            }
                                       m[i][j]=fatt;
                                       n=j;
                                       for( ;n>i;n--){
                                                 fatt*=n;
                                       }
                                       m[i][j]+=fatt;
                                       m[j][i]=m[i][j];
                      }
     }
     	printf("Scriviamo la matrice\n");
		for (i = 0; i < N; i++) {
			for (j = 0; j < M; j++) {
				printf("m[%d][%d] = %d\n",i,j,m[i][j]);
			}
		}
for(i=0;i<N;i++){
                 free(m[i]);
}
free(m);
system ("PAUSE");
return 0;
}

Grazie Ragazzi!

Risposte
Rggb1
"Mrhaha":
...ma uno non mi viene,e sinceramente non capisco dove stia sbagliando!

Nemmeno io, magari dacci qualche indizio: non riesci a compilare, non torna il risultato, il programma va in errore, hai finito il caffè, o che altro?

Mrhaha
Il caffè forse non era buono! :-D
Rggb quando mi calcola la matrice il programma non è corretta!
Non è la matrice che io cerco,non soddisfa l'esercizio insomma!

vict85
Alcune considerazioni:

1) A livello "professionale" la memorizzazione della matrice come puntatori di puntatori o come array bidimensionali è sconsigliato e generalmente evitato se non è proprio necessario (cosa che personalmente penso non sia mai il caso). L'uso più comune, e che garantisce un maggiore controllo sulla matrice, è quella di usare un array di dimensione \(m\times n\) e di richiamare l'elemento usando l'indice \(in+j\) con \(0\le i < m\) e \(0\le j < n\).
2) Il fatto che \(0! = 1\) rende le cose un attimo più complicate infatti \(m_{i0} = m_{0i} = i! + 0! = i!+1\). Quindi si ricava che \(m_{ij} = m_{i0} + m_{0j} - 2\) invece del più intuitivo \(m_{ij} = m_{0i} + m_{0j}\). Si ha inoltre che \(m_{ij} = m_{ji}\). Siccome \(m_{00} = 0!+0! = 1+1 = 2\) e \(i! = (i-1)!i\) ricavo la formula \(m_{i0} = i(m_{i-10}-1) + 1\)
3) Scrivi due volte su tutti gli elementi perché non hai imposto che \(j\) sia sempre maggiore o uguale di \(i\) (o viceversa) ma hai comunque messo una riga in cui scrivi sull'elemento con righe e colonne scambiate durante il ciclo. Inoltre per quanto tu abbia ottimizzato il calcolo del fattoriale in ogni "turno" tu lo ricalcoli per ogni elemento della matrice.

In generale penso che il problema, a parte nella scelta dell'algoritmo e della memorizzazione dei dati, sia nel fatto che i numeri sono troppo grandi per essere memorizzati in un int. Già il fattoriale di \(8\) è superiore a \(32768\) cioè \(2^{15}\), e per superare \(2^{32}\) basta \(13!\). Mentre un int a 64 bit non contiene il fattoriale di \(21\).

P.S: ho ritenuto che fosse \(i!+j!\) invece del tuo \((i!)!+j!\) (parentesi mie). Infatti il fattoriale del fattoriale di \(4\) già non è contenuto in un int a \(64\) bit. Il codice comunque calcola quello che ho analizzato io quindi penso che il tuo sia un errore di digitazione.

vict85
In ogni caso c'è anche un errore nel calcolo del fattoriale di \(j\). Probabilmente il problema è un copia incolla :roll: . Per correggerlo ti basta mettere \(j=i\) invece di \(j=0\) nel secondo ciclo.

Mrhaha
"vict85":

...
P.S: ho ritenuto che fosse \(i!+j!\) invece del tuo \((i!)!+j!\) (parentesi mie). Infatti il fattoriale del fattoriale di \(4\) già non è contenuto in un int a \(64\) bit. Il codice comunque calcola quello che ho analizzato io quindi penso che il tuo sia un errore di digitazione.


Hai perfettamente ragione! Ora aggiusto!

Ci penso un attimo!

Mrhaha
Effettivamente era quello l'errore! :-D
Mannaggia a me! :-D

Tu dici che non conviene allocare una matrice dinamicamente,perchè?
Cioè io faccio il ragionamento "Mi da solo la memoria che mi serve!". Perchè è migliore un'allocazione statica?

vict85
"Mrhaha":
Effettivamente era quello l'errore! :-D
Mannaggia a me! :-D

Tu dici che non conviene allocare una matrice dinamicamente,perchè?
Cioè io faccio il ragionamento "Mi da solo la memoria che mi serve!". Perchè è migliore un'allocazione statica?


No, io intendo dire che è meglio allocare un array invece che un array di array. Ha soprattutto vantaggi perché la matrice è tutta allocata in un gruppo unico e quindi costruire gli algoritmi in modo da usare al meglio la memoria.

Mrhaha
Ah scusami,avevo capito una cosa per un'altra! Grazie ancora! :D

Rispondi
Per rispondere a questa discussione devi prima effettuare il login.