Esercizio metodo con array

di il
5 risposte

Esercizio metodo con array

Ciao a tutti, avrei bisogno di una mano con questo esercizio!! Sto imparando Java e ancora non mi sono chiari alcuni concetti
L'esercizio mi chiede : Scrivere un metodo Java che restituisca il valore minimo e il valore massimo tra i valori presenti in un
array a di int passato per riferimento tramite argomento.

Ho scritto questo codice:
public class diciannove{             
    
	public static int[] max_min(int[] a){     
		
		int max=a[0];
		int min=a[0];
		int[] r=null;
		
		for(int i=0;i<a.length;i++){
			
			if(a[i] > a[i+1] && a[i]>max){
				max= a[i];
			}else if(a[i] < a[i+1] && a[i]<min){
				min= a[i];
			}
			
	    r = new int[2];   // SBAGLIATO???
            r[0]=max;
            r[1]=min;
			
		}
		return r;
	}
	
	public static void main(String[] args){   // USO IL METODO 
		
		int[] maxmin;                      // SBAGLIATO???
		maxmin= new int[5];
		max_min(maxmin);
	
		Display.println("Il valore di max min e': "+maxmin);
	}
}
Ovviamente non funziona Sono sicuro di aver sbagliato le parti commentate, non mi è ancora chiara la gestione degli array e l'invocazione di metodi.
Potreste dirmi dove sta l'errore? Magari con breve spiegazione!!
Grazie

p.s. Display è una classe che mi è stata fornita per stampare.

5 Risposte

  • Re: Esercizio metodo con array

    Jevilik ha scritto:


    Sono sicuro di aver sbagliato le parti commentate, non mi è ancora chiara la gestione degli array e l'invocazione di metodi.
    Potreste dirmi dove sta l'errore? Magari con breve spiegazione!!
    Partiamo dal metodo main. La prima istruzione tecnicamente non è sbagliata, stai dichiarando un array di interi, ma senza inizializzarlo, cosa che fai subito dopo.

    In genere ti conviene farlo subito, ad esempio una normale inizializzazione si fa con :
    
    int [] maxmin = new int [5]; // o qualsiasi altra lunghezza naturalmente
    
    Con questa istruzione l'array è stato creato, ma all'interno non sono ancora stati assegnati i valori, che sono messi a 0 in automatico (questo dipende dal contenuto dell' array, per una classe standard avrai tutti gli elementi null, ma un tipo primitivo come int non può essere null, controlla la tabella "Default Values" a questo indirizzo per maggiori dettagli, subito dopo la lista dei tipi primitivi).

    L'istruzione successiva in cui richiami il metodo maxmin, invece, è sprecata, in quanto il metodo verrà sì eseguito, ma il valore di ritorno del metodo (quel int [] scritto subito prima del nome del metodo, da non confondere con quell' int [] a, che è un argomento passato al metodo) non viene salvato in nessuna maniera, è perso.

    Questo non vuol dire che ogni volta che esegui un metodo tu debba salvarti il valore di ritorno in una variabile (se il metodo ritorna void non lo farai mai, e anche in altri casi), ma in questo caso è necessario (senza cambiare il metodo max_min almeno, ma qui non serve).

    Quindi nel main potresti fare qualcosa di questo tipo :
    
    // crei l'array di cui vuoi trovare il massimo e il minimo
    int [] a = new int [5];
    
    /* 
    ora l'array a contiene solo zeri, puoi settare manualmente i valori o anche settare i valori direttamente nella inizializzazione, scrivendo ad es. :
    int [] a = {2, 3, 1, 6, -2};
    */
    
    // chiami il metodo per trovare massimo e minimo, e salvi il risultato nel vettore maxmin
    int [] maxmin = max_min (a);
    // stampi il contenuto di maxmin ...
    
    Ora il valore di ritorno (quello che ad ora stai salvando nel vettore r in max_min, e viene restituito dal return) viene memorizzato nell'array maxmin, per usarlo come meglio credi in seguito.
    ______________________________________________________________________________

    Per quanto riguarda il metodo max_min, devi stare attento a come esegui il ciclo.

    Va benissimo inizializzare massimo e minimo al primo valore dell'array, sempre che l'array non sia vuoto o null (per ora puoi risparmiarti il controllo).
    Poi però il ciclo dovrebbe partire dalla posizione 1, tanto alla posizione 0 hai già controllato il valore.

    Tu devi valutare il resto degli elementi presenti nell'array, e memorizzare il nuovo massimo e il nuovo minimo man mano che lo trovi.
    E' più facile di come stai facendo tu in questo momento, basta la seconda condizione dell'if.

    La prima condizione dei due if, oltre a essere superflua, ti causerà un errore in esecuzione, perché l'indice [i+1] non esisterà quando controlli l'ultimo elemento (ArrayIndexOutOfBoundsException).

    La restituzione di r invece va bene, ma r va creato all'esterno del ciclo, quando hai controllato tutti gli elementi, farlo all'interno non ha senso.

    Quindi puoi fare qualcosa tipo :
    
    for (/* ....*/) {
    	// corpo del ciclo ...
    }
    int [] r = {max, min};
    return r;
    
    Il modo in cui restituisci massimo e minimo può variare, in questo caso li metti in un array di int, ma devi scegliere tu (se non hai indicazioni) la posizione del massimo e del minimo, e potrebbe non essere chiaro nel resto del codice.
    Potresti anche resituire un oggetto che contenga solo i campi massimo e minimo, con i soli metodi get per leggerli in seguito, ma questa è un'altra storia ...
  • Re: Esercizio metodo con array

    Va in
    java.lang.ArrayIndexOutOfBoundsException: 5
    su questa riga
    if (a > a[i + 1] && a > max) {
    perchè quando esamina l'ultimo valore dell array (ossia i=4, ricorda che gli indici dell array partono da 0 e non da 1)
    cerca di prendere il valore a[i+1] (ossia a[5]) ma quel valore non esiste.

    r = new int[2]; // SBAGLIATO??? ad ogni ciclo lo inizializzi. E' sufficiente inizializzarlo prima del ciclo

    int[] maxmin; // SBAGLIATO???
    no ma potresti inizializzarlo in una unica riga.
  • Re: Esercizio metodo con array

    Ok, inizio con il ringraziare entrambi detto ciò.. ho fatto dei cambiamenti nel codice ma ancora non riesco ad ottenere il risultato giusto
    public class diciannove{             // CLASSE 
        
    	public static int[] max_min(int[] a){     //  METODO 
    		
    		int max=a[0];
    		int min=a[0];
    	
    		
    		for(int i=0;i<a.length-1;i++){
    			
    			if(a[i] > a[i+1] && a[i]>max){
    				max= a[i];
    			}else if(a[i] < a[i+1] && a[i]<min){
    				min= a[i];
    			}
    			
    		
    		}
    		int [] r = new int[2];   
                r[0]=max;
                r[1]=min;
            return r;
    	}
    	
    	public static void main(String[] args){   // USO IL METODO 
    		
    		
    		int [] a = {2, 3, 1, 6, -2};
    		int [] maxmin = max_min (a);
    	
    		Display.println("Il valore di max min e': "+maxmin);
    		
    	}
    }
    Il programma adesso parte ma, non restituisce alcun valore sensato;
    Va benissimo inizializzare massimo e minimo al primo valore dell'array, sempre che l'array non sia vuoto o null (per ora puoi risparmiarti il controllo).
    Poi però il ciclo dovrebbe partire dalla posizione 1, tanto alla posizione 0 hai già controllato il valore.
    Quindi se non lo volessi inizializzare dovrei scrivere solamente:
    int [] max= new int[1]
    		max [] = a[i]; // nell'if  <--- 
    

    La prima condizione dei due if, oltre a essere superflua, ti causerà un errore in esecuzione, perché l'indice [i+1] non esisterà quando controlli l'ultimo elemento (ArrayIndexOutOfBoundsException).
    Ma se metto solo la seconda condizione e quindi mi ricavo il min, il max come faccio a gestirlo

    E poi.. nel momento in cui stampo, mettendo
    Display.println("Il valore di max min e': "+maxmin);
    in maxmin ho r[0] ed r[1] giusto? Quindi in teoria dovrei stampare una cosa del tipo:
    a = { 2 5 7 13 1} (esempio di vettore)
    stampa: 113
    Come gestisco gli spazi tra min e max in modo da stampare 1 e 13?? Posso scrivere al posto di maxmin quando stampo r[0] ed r[1]?
  • Re: Esercizio metodo con array

    Jevilik ha scritto:


    Il programma adesso parte ma, non restituisce alcun valore sensato;
    Se non sbaglio con i dati che hai inserito dovresti ottenere 6 come massimo e 1 come minimo.
    Il massimo è giusto, solo il minimo è sbagliato. E ti dovresti accorgere subito del perché : hai inserito come condizione del ciclo
    
    i<a.length-1
    
    Quindi il ciclo termina prima di aver controllato l'ultimo elemento, e il minimo che ti restituisce è il precedente che ha trovato, quindi 1 al posto di -2.
    Non ha senso ciclare fino a a.length - 1, tu l'hai fatto probabilmente per evitare l'errore in esecuzione, ma non è questo il modo giusto, ci torniamo dopo.

    Jevilik ha scritto:



    Quindi se non lo volessi inizializzare dovrei scrivere solamente:
    int [] max= new int[1]
    		max [] = a[i]; // nell'if  <--- 
    

    No.
    Come hai fatto prima andava bene, ti volevo solo far ragionare sull'indice da cui far partire il controllo.
    Tu all'inizio poni sia il massimo sia il minimo pari al primo elemento del vettore.
    Quindi se fai il ciclo che parte dalla posizione 0, al primo passo ti stai chiedendo:

    a [0] > a [0] ?
    a [0] < a [0] ?

    Ovviamente no, quindi il primo giro del ciclo è inutile, fai partire il ciclo da 1.

    Potresti anche non farlo, fai finta per un attimo di dover trovare solo il massimo, dichiari ad esempio :
    
    int max = 0;
    
    Poi scansioni tutti gli elementi del vettore e se l'elemento corrente è maggiore del massimo poni max = a .
    Il fatto è che se hai un vettore composto da numeri negativi, in questo caso, otterresti come massimo 0, perché non viene mai aggiornato.
    Quindi se segui questa strada devi scegliere un valore che sei sicuro venga aggiornato in seguito (ad esempio in questo caso fissi int max = Integer.MIN_VALUE, qualsiasi intero in seguito sarà maggiore o uguale).

    Ma va meglio come stavi facendo tu, basta aggiornare l'indice di partenza

    Jevilik ha scritto:



    Ma se metto solo la seconda condizione e quindi mi ricavo il min, il max come faccio a gestirlo


    Hai frainteso questa parte.

    
    if(a[i] > a[i+1] && a[i]>max)
    
    La prima condizione è a > a[i+1]. Questa parte non serve a niente, per trovare il massimo basta controllare tutti gli elementi e aggiornare il massimo quando ne trovi uno maggiore, non ti serve controllare che il valore corrente sia maggiore del successivo.
    Lascia solo la seconda condizione, cioè essere maggiore del massimo (o minore del minimo nel secondo caso). Così risolvi anche il problema della NullPointerException e puoi fare il ciclo da 1 ad a.length senza alcun problema.


    Jevilik ha scritto:


    E poi.. nel momento in cui stampo, mettendo
    Display.println("Il valore di max min e': "+maxmin);
    in maxmin ho r[0] ed r[1] giusto? Quindi in teoria dovrei stampare una cosa del tipo:
    a = { 2 5 7 13 1} (esempio di vettore)
    stampa: 113
    Come gestisco gli spazi tra min e max in modo da stampare 1 e 13?? Posso scrivere al posto di maxmin quando stampo r[0] ed r[1]?
    Non so come sia scritta la classe Display, ma normalmente se stampi a video un vettore con System.out.print () o System.out.println () non ottieni il contenuto dell'array, ma una stringa ben poco interpretabile.
    Quindi o ti fai un metodo che riceve un array e cicla per stamparne il contenuto (separato da spazi o in qualsiasi altro modo), oppure puoi benissimo prendere i valori direttamente dall'array che hai nel main e li concateni come più ti piace, ad es. :
    
    int [] maxmin = max_min (a);
    System.out.println ("Il valore del massimo è : " + maxmin [0] + ", il minimo vale invece : " + maxmin [1]);
    
    L'importante è che in questo caso devi sapere come li hai inseriti nel metodo ...
  • Re: Esercizio metodo con array

    problema della NullPointerException
    Si, esatto! Avevo messo il -1 per risolvere quel problema
    Quindi o ti fai un metodo che riceve un array e cicla per stamparne il contenuto (separato da spazi o in qualsiasi altro modo), oppure puoi benissimo prendere i valori direttamente dall'array che hai nel main e li concateni come più ti piace
    Quindi conoscendo i valori dell'array all'interno del metodo, al momento della stampa posso trattare nel main il return come fosse un vettore normale dichiarato nel main
    Comunque adesso funziona tutto, grazie mille!
Devi accedere o registrarti per scrivere nel forum
5 risposte