[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));
}
}