[Java] Programma Matrice (Array di array)
Ciao! eccomi di nuovo...premettendo che odio gli array di array
sto facendo questo esercizio:
La classe MatriceDiNomi l'ho fatta:
e anche la classe di Prova:
compila senza errori, però quando finisco di inserire i nomi nella matrice mi compare l'errore (sull'output di sistema):
Exception in thread "main" java.lang.NullPointerException
at MatriceDiNomi.nomePi¨Corto(MatriceDiNomi.java:29)
at ProvaMatriceDiNomi.main(ProvaMatriceDiNomi.java:19)
ma io non capisco dove sia l'errore!!
mi potete aiutare?

Esercizio 1 Un oggetto della classe MatriceDiNomi rappresenta una matrice rettangolare i cui elementi sono nomi di persona (stringhe). Lo scheletro della classe è il seguente: class MatriceDiNomi { /* variabile che memorizza la matrice di nomi */ private String[][] mat; /* costruttore: permette di creare un oggetto che rappresenta l’insieme delle stringhe contenute nell’array di array matrice */ public MatriceDiNomi (String[][] matrice){...} /* restituisce il nome di lunghezza minima nell’intera matrice */ public String nomePiùCorto (){...} /* restituisce un array di interi che dice qual è la lunghezza totale dei nomi su ciascuna riga */ public int[] lunghTotRiga (){...} /* restituisce il nome di lunghezza massima sulla colonna k specificata */ public String nomePiùLungoNellaColonna (int k){...} } Scrivere il corpo dei metodi della classe MatriceDiNomi e definire inoltre una classe di prova il cui metodo speciale main svolga le seguenti funzioni. - Fa inserire all’utente una matrice di nomi a sua scelta (anche le dimensioni della matrice sono scelti dall’utente). - Visualizza all’utente il nome più corto dell’intera matrice. - Visualizza all’utente il numero totale di caratteri dei nomi su ogni riga - Per ogni colonna della matrice, visualizza all’utente il nome più lungo nella colonna.
La classe MatriceDiNomi l'ho fatta:
class MatriceDiNomi { /* variabile che memorizza la matrice di nomi */ private String[][] mat; /* costruttore: permette di creare un oggetto che rappresenta l’insieme delle stringhe contenute nell’array di array matrice */ public MatriceDiNomi (String[][] matrice){ int righe=matrice.length; int colonne=matrice[0].length; this.mat=new String[righe][colonne]; for(int i=0; i<righe;i++){ for(int j=0;j<colonne;j++){ this.mat[i][j]=matrice[i][j]; } } } /* restituisce il nome di lunghezza minima nell’intera matrice */ public String nomePiùCorto (){ int righe=this.mat.length; int colonne=this.mat[0].length; String[][] matrice=new String[righe][colonne]; String s=""; for(int i=0;i<righe;i++){ for(int j=0;j<colonne;j++){ if(matrice[i][j].length()<matrice[righe][colonne].length()) s+=matrice[i][j]; } } return s; } /* restituisce un array di interi che dice qual è la lunghezza totale dei nomi su ciascuna riga */ public int[] lunghTotRiga (){ int[] lunghezzaRighe = new int[this.mat.length]; int righe=this.mat.length; int colonne=this.mat[0].length; String[][] matrice=new String[righe][colonne]; for(int i=0;i<righe;i++){ lunghezzaRighe[i]=0; for(int j=0;j<colonne;j++){ lunghezzaRighe[i]+=matrice[i][j].length(); } } return lunghezzaRighe; } /* restituisce il nome di lunghezza massima sulla colonna k specificata */ public String nomePiùLungoNellaColonna (int k){ String nome=""; int righe=this.mat.length; int colonne=this.mat[0].length; String[][] matrice=new String[righe][colonne]; for(int i=0;i<righe;i++){ if(matrice[i][k].length()>matrice[righe][k].length()) nome+=matrice[i][k]; } return nome; } }
e anche la classe di Prova:
class ProvaMatriceDiNomi{ public static void main (String[] args){ InputWindow in=new InputWindow(); OutputWindow out=new OutputWindow(); int righe = in.readInt ("Inserisci le righe della matrice di nomi"); int colonne = in.readInt ("Inserisci le colonne della matrice di nomi"); String[][] mat=new String[righe][colonne]; MatriceDiNomi matrice=new MatriceDiNomi(mat); for(int i=0; i<mat.length;i++){ for(int j=0;j<mat[0].length;j++){ mat[i][j]=in.readString("Inserisci elemento di riga "+i+" e colonna "+j); out.writeln(mat[i][j]+" "); } } out.writeln(matrice.nomePiùCorto()); out.writeln(matrice.lunghTotRiga()); int k=in.readInt("Inserisci la colonna da considerare"); out.writeln(matrice.nomePiùLungoNellaColonna(k)); } }
compila senza errori, però quando finisco di inserire i nomi nella matrice mi compare l'errore (sull'output di sistema):
Exception in thread "main" java.lang.NullPointerException
at MatriceDiNomi.nomePi¨Corto(MatriceDiNomi.java:29)
at ProvaMatriceDiNomi.main(ProvaMatriceDiNomi.java:19)
ma io non capisco dove sia l'errore!!

mi potete aiutare?
Risposte
Per ora focalizziamoci su dove dà errore:
1) da un punto di vista del codice, non esiste l'elemento "matrice[righe][colonne]", quindi è quello il riferimento ad un puntatore nullo. Ricorda che gli indici degli array partono da 0 e arrivano a length-1, per un totale di length elementi(*). Quindi, se vuoi riferirti all'ultimo elemento devi usare una espressione tipo "matrice[righe-1][colonne-1]";
2) da un punto di vista semantico... non ho capito cosa volevi fare; ti viene richiesto di ritornare il nome più corto fra tutti, rivedi un po' il funzionamento. Quel che hai codificato (direi) è una cosa del genere:
- considera tutti gli elementi di una matrice di stringhe
- se l'elemento considerato ha lunghezza minore dell'ultimo elemento della matrice, accoda tale elemento alla stringa 's'
- ritorna il valore di 's'
(*) NOTA
E' stranissimo che una cosa del genere, semplicissima, generi tanta confusione (non solo tua, ma di molti utenti che postano domande simili): se un insieme ha $n$ elementi che sono numerati partendo da $0$, ovviamente la numerazione sarà $0, 1, 2, ..., n-1$
/* restituisce il nome di lunghezza minima nell’intera matrice */ public String nomePiùCorto (){ int righe=this.mat.length; int colonne=this.mat[0].length; String[][] matrice=new String[righe][colonne]; String s=""; for(int i=0;i<righe;i++){ for(int j=0;j<colonne;j++){ if(matrice[i][j].length()<matrice[righe][colonne].length()) s+=matrice[i][j]; } } return s; }
1) da un punto di vista del codice, non esiste l'elemento "matrice[righe][colonne]", quindi è quello il riferimento ad un puntatore nullo. Ricorda che gli indici degli array partono da 0 e arrivano a length-1, per un totale di length elementi(*). Quindi, se vuoi riferirti all'ultimo elemento devi usare una espressione tipo "matrice[righe-1][colonne-1]";
2) da un punto di vista semantico... non ho capito cosa volevi fare; ti viene richiesto di ritornare il nome più corto fra tutti, rivedi un po' il funzionamento. Quel che hai codificato (direi) è una cosa del genere:
- considera tutti gli elementi di una matrice di stringhe
- se l'elemento considerato ha lunghezza minore dell'ultimo elemento della matrice, accoda tale elemento alla stringa 's'
- ritorna il valore di 's'
(*) NOTA
E' stranissimo che una cosa del genere, semplicissima, generi tanta confusione (non solo tua, ma di molti utenti che postano domande simili): se un insieme ha $n$ elementi che sono numerati partendo da $0$, ovviamente la numerazione sarà $0, 1, 2, ..., n-1$
ecco ok, questa cosa degli n elementi che quindi sono 0,1,2,...,n-1 l'ho capita ma la mia intenzione non era di confrontare l'elemento di posto ij con l'ultimo...volevo confrontare ij con TUTTA la matrice e farmi ridare l'elemento con meno caratteri (per questo ho usato length() )...pensavo che inserendo matrice[righe][colonne] avrebbe controllato tutta la matrice...ma non ero sicuro ed evidentemente sbagliavo (tanto che matrice[righe][colonne] nemmeno esiste come giustamente mi hai fatto notare)...
come dovrei fare allora?
come dovrei fare allora?
Nel modo più classico:
- prendi un elemento a tua scelta della matrice e lo metti in s; il primo, di indici [0][0], è normalmente la scelta più semplice;
- fai un ciclo per tutti gli elementi:
- - se l'elemento in questione ha lunghezza minore di s:
- - - memorizzi il nuovo elemento in s.
Alla fine 's' sarà (uno degli) l'elemento con lunghezza minore.
- prendi un elemento a tua scelta della matrice e lo metti in s; il primo, di indici [0][0], è normalmente la scelta più semplice;
- fai un ciclo per tutti gli elementi:
- - se l'elemento in questione ha lunghezza minore di s:
- - - memorizzi il nuovo elemento in s.
Alla fine 's' sarà (uno degli) l'elemento con lunghezza minore.
ok grazie ho risolto!!
scrivo i codici in caso interessino a qualcuno.


scrivo i codici in caso interessino a qualcuno.
class MatriceDiNomi { /* variabile che memorizza la matrice di nomi */ private String[][] mat; /* costruttore: permette di creare un oggetto che rappresenta l’insieme delle stringhe contenute nell’array di array matrice */ public MatriceDiNomi (String[][] matrice){ int righe=matrice.length; int colonne=matrice[0].length; this.mat=new String[righe][colonne]; for(int i=0; i<righe;i++){ for(int j=0;j<colonne;j++){ this.mat[i][j]=matrice[i][j]; } } } /* restituisce il nome di lunghezza minima nell’intera matrice */ public String nomePiùCorto (){ int righe=this.mat.length; int colonne=this.mat[0].length; String corto=this.mat[0][0]; for(int i=0;i<righe;i++){ for(int j=0;j<colonne;j++){ if(this.mat[i][j].length()<corto.length()) corto=this.mat[i][j]; } } return corto; } /* restituisce un array di interi che dice qual è la lunghezza totale dei nomi su ciascuna riga */ public int[] lunghTotRiga (){ int righe=this.mat.length; int colonne=this.mat[0].length; int[] lunghezzaRighe = new int[righe]; for(int i=0;i<righe;i++){ int somma=0; for(int j=0;j<colonne;j++){ somma+=this.mat[i][j].length(); } lunghezzaRighe[i]=somma; } return lunghezzaRighe; } /* restituisce il nome di lunghezza massima sulla colonna k specificata */ public String nomePiùLungoNellaColonna (int k){ int righe=this.mat.length; int colonne=this.mat[0].length; String nomeLungo=this.mat[0][0]; for(int i=0;i<righe;i++){ if(this.mat[i][k].length()>nomeLungo.length()) nomeLungo=this.mat[i][k]; } return nomeLungo; } }
class ProvaMatriceDiNomi{ public static void main (String[] args){ InputWindow in=new InputWindow(); OutputWindow out=new OutputWindow(); int righe = in.readInt ("Inserisci le righe della matrice di nomi"); int colonne = in.readInt ("Inserisci le colonne della matrice di nomi"); String[][] mat=new String[righe][colonne]; for(int i=0; i<mat.length;i++){ out.writeln(""); for(int j=0;j<mat[0].length;j++){ mat[i][j]=in.readString("Inserisci elemento di riga "+i+" e colonna "+j); out.write(mat[i][j]+" "); } } MatriceDiNomi matrice=new MatriceDiNomi(mat); out.writeln("\n"+"\nIl nome più corto è: "+matrice.nomePiùCorto()); int[] lunghezzaRighe=matrice.lunghTotRiga(); for(int i=0;i<righe;i++){ out.writeln("\nLunghezza riga "+i+": "+lunghezzaRighe[i]); } int k=in.readInt("Inserisci la colonna da considerare"); out.writeln("\nIl nome più lungo nella colonna "+k+" è: "+matrice.nomePiùLungoNellaColonna(k)); } }