[Java] Programma Matrice (Array di array)

alex170
Ciao! eccomi di nuovo...premettendo che odio gli array di array :evil: sto facendo questo esercizio:

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!! :cry:

mi potete aiutare?

Risposte
Rggb1
Per ora focalizziamoci su dove dà errore:
   /* 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$

alex170
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?

Rggb1
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.

alex170
ok grazie ho risolto!! :P :P
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));

	}
}

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