Matrice di 30 numeri diversi.

di il
12 risposte

Matrice di 30 numeri diversi.

Salve, ho questo esercizio: Creare una classe che ha come proprietà statica una matrice “mat” 3 x 4.
La classe ha i seguenti metodi statici:
? ins() che inserire nella matrice numeri casuali compresi tra 1 e 30. Tutti i numeri della matrice devono
essere diversi.
. stampa() i valori della matrice;

package pkg1;

import java.util.*;

public class NumCas {

	private static int[][] mat=new int[3][4];

	public static void ins() {

		List lis = new ArrayList();

		Integer a;
		for (int i = 0; i < 30; i++) {
			lis.add(i, (Object) (a = (i + 1)));
		}
		for (int i = 0; i < 3; i++) {
			for (int j = 0; j < 4; j++) {

				int indiceCor = (int) (Math.random() * 30);
				mat[i][j]=(int)(lis.remove(indiceCor));
			}
		}
			
		}
		
		public static void stampa() {
			for(int i=0; i<3; i++) {
			
				for(int j=0; j<4; j++) {
					System.out.println(mat[i][j]);
				}
			}
			
		}
		
	}
Il programma non funziona mi da questo errore:

Exception in thread "main" java.lang.IndexOutOfBoundsException: Index 28 out of bounds for length 25
	at java.base/jdk.internal.util.Preconditions.outOfBounds(Preconditions.java:64)
	at java.base/jdk.internal.util.Preconditions.outOfBoundsCheckIndex(Preconditions.java:70)
	at java.base/jdk.internal.util.Preconditions.checkIndex(Preconditions.java:248)
	at java.base/java.util.Objects.checkIndex(Objects.java:359)
	at java.base/java.util.ArrayList.remove(ArrayList.java:504)
	at EsempioEsame7/pkg1.NumCas.ins(NumCas.java:21)
	at EsempioEsame7/pkg1.ProgNumCas.main(ProgNumCas.java:9)

12 Risposte

  • Re: Matrice di 30 numeri diversi.

    mark13 ha scritto:


    Il programma non funziona mi da questo errore:
    
    Exception in thread "main" java.lang.IndexOutOfBoundsException: Index 28 out of bounds for length 25
    A parte il fatto che ci sono diverse cose inutili (tipo il cast a Object) e non hai usato List/ArrayList "parametrizzati" ma il vero problema è la moltiplicazione del random per 30.
    Quando hai 30 elementi è corretto tirare fuori un indice da 0 a 29 (inclusi). Ma man mano che rimuovi fisicamente dalla lista, l'indice massimo deve anche scalare!
  • Re: Matrice di 30 numeri diversi.

    Man mano che il ciclo rimuove gli elementi, non puoi continuare a scegliere l'indice così come fai perché potresti puntare ad un elemento che non esiste più. Chiaro?
  • Re: Matrice di 30 numeri diversi.

    Salve, ho corretto un poco l'esercizio, ed alla fine mi funziona:
    
    
    import java.util.*;
    
    public class NumCas {
    
    	private static int[][] mat=new int[3][4];
    
    	public static void ins() {
    
    		List <Integer>lis = new ArrayList();
    
    		Integer a;
    		for (int i = 0; i < 30; i++) {
    			lis.add(i,  (a = (i + 1)));
    		}
    		for (int i = 0; i < 3; i++) {
    			for (int j = 0; j < 4; j++) {
                    
    				if(i==0) {
    				int indiceCor = (int) (Math.random() * (30-1));
    				mat[i][j]=(int)(lis.remove(indiceCor));
    				}
    				if(i==1) {
    					int indiceCor = (int) (Math.random() * (26-1));
    					mat[i][j]=(int)(lis.remove(indiceCor));
    				}
    				if(i==2) {
    					int indiceCor = (int) (Math.random() * (22-1));
    					mat[i][j]=(int)(lis.remove(indiceCor));
    				}
    				}
    			}
    		}
    			
    		
    		
    		public static void stampa() {
    			for(int i=0; i<3; i++) {
    			
    				for(int j=0; j<4; j++) {
    					System.out.print(mat[i][j]+" ");
    					
    				}
    				System.out.print("\n");
    			}
    			
    		}
    	}
    
    Però quando eseguo il programma un paio di volte, almeno una volta mi compare il seguente errore:

    Exception in thread "main" java.lang.IndexOutOfBoundsException: Index 27 out of bounds for length 27
    at java.base/jdk.internal.util.Preconditions.outOfBounds(Preconditions.java:64)
    at java.base/jdk.internal.util.Preconditions.outOfBoundsCheckIndex(Preconditions.java:70)
    at java.base/jdk.internal.util.Preconditions.checkIndex(Preconditions.java:248)
    at java.base/java.util.Objects.checkIndex(Objects.java:359)
    at java.base/java.util.ArrayList.remove(ArrayList.java:504)
    at EsempioEsame7/pkg1.NumCas.ins(NumCas.java:22)
    at EsempioEsame7/pkg1.ProgNumCas.main(ProgNumCas.java:9)


    con Index e length diverisi ogni volta.
  • Re: Matrice di 30 numeri diversi.

    Se hai un errore allora il programma non funziona.
    Rivedi il codice e il ragipnamento che fai
  • Re: Matrice di 30 numeri diversi.

    mark13 ha scritto:


    				if(i==0) {
    				int indiceCor = (int) (Math.random() * (30-1));
    				mat[i][j]=(int)(lis.remove(indiceCor));
    				}
    				if(i==1) {
    					int indiceCor = (int) (Math.random() * (26-1));
    					mat[i][j]=(int)(lis.remove(indiceCor));
    				}
    				if(i==2) {
    					int indiceCor = (int) (Math.random() * (22-1));
    					mat[i][j]=(int)(lis.remove(indiceCor));
    				}
    Questa parte non ha assolutamente alcun senso.
    E quando prima dicevo "l'indice massimo deve anche scalare", banalmente si usa il size() della lista! Perché questo diminuisce facendo dei remove!
  • Re: Matrice di 30 numeri diversi.

    Scusate non vi ho dato la soluzione completa:
    Creare una lista di 30 numeri da 1 fino a 30. Poi prendere il numero casuale “x” generato (compreso tra 0 e 29) e
    prendere il numero nella posizione x. Poi cancellare dalla lista il numero in quella posizione. Esempio:
    lista=1 2 3 4 5 6 7 8 9 … x=4 e quindi prendi il numero nella posizione 4 ossia il numero 5.
    Poi viene cancellato il numero 5 e la lista diventa lista=”1 2 3 4 6 7 8 9 …..”
    etc….
    Io ho implementato come avete visto sopra la soluzione proposta dal professore. In particolare, ho usato il metodo remove() per memorizzare nella matrice l'elemento cancellato.
  • Re: Matrice di 30 numeri diversi.

    mark13 ha scritto:


    Io ho implementato come avete visto sopra la soluzione proposta dal professore. In particolare, ho usato il metodo remove() per memorizzare nella matrice l'elemento cancellato.
    Ok, lo ripeto meglio. La parte:
    				if(i==0) {
    				int indiceCor = (int) (Math.random() * (30-1));
    				mat[i][j]=(int)(lis.remove(indiceCor));
    				}
    				if(i==1) {
    					int indiceCor = (int) (Math.random() * (26-1));
    					mat[i][j]=(int)(lis.remove(indiceCor));
    				}
    				if(i==2) {
    					int indiceCor = (int) (Math.random() * (22-1));
    					mat[i][j]=(int)(lis.remove(indiceCor));
    				}
    è SBAGLIATA.

    Primo: non ha alcun senso fare più if per ciascuna "riga" della matrice (se avesse 10 righe che fai ... 10 if ???)
    Secondo: 30-1 fa sì che l'indice estratto sia tra 0 (incluso) e 29 (escluso!!) ma così tra l'altro ignora l'ultimo elemento.
    Terzo: anche ammesso di mettere 30 (e non 30-1), il if(i==0) viene ripetuto 4 volte (perché le righe hanno 4 colonne, da indice j). Ma se il 30 è fisso, al primo giro ok ma al secondo giro non è impossibile che tiri fuori 29 che non esiste più perché almeno un elemento è stato rimosso!

    Insomma, quello è sbagliato/insensato!!

    La soluzione l'ho detta prima: si usa il size() della lista
  • Re: Matrice di 30 numeri diversi.

    Ciao andbin, si hai ragione. Stavo appunto correggendo il codice inserendo il metodo size():
    
    public static void ins() {
    
    		List <Integer>lis = new ArrayList();
    
    		Integer a;
    		for (int i = 0; i < 30; i++) {
    			lis.add(i,  (a = (i + 1)));
    		}
    		for (int i = 0; i < 3; i++) {
    			for (int j = 0; j < 4; j++) {
                    
    				int indiceCor = (int) (Math.random() * (lis.size()));
    				mat[i][j]=(int)(lis.remove(indiceCor));
    				
    				}
    			}
    		}
    
    Effettivamente il programma non genera più errore indipendentemente da quante volte lo esegua.
  • Re: Matrice di 30 numeri diversi.

    mark13 ha scritto:


    int indiceCor = (int) (Math.random() * (lis.size()));
    
    Corretto. (le parentesi attorno a lis.size() sono superflue (Math.random() * (lis.size())) )
  • Re: Matrice di 30 numeri diversi.

    Ok, grazie.
  • Re: Matrice di 30 numeri diversi.

    Perché remove? basta lo shuffle
    
        public static void ins() {
          java.util.List<Integer> l = new java.util.ArrayList<>();
          for(int i=1;i<=30;i++)
            l.add(i);
          java.util.Collections.shuffle(l);
          for(int i=0;i<12;i++)
            mat[i/4][i%4] = l.get(i);      
        }  
    
  • Re: Matrice di 30 numeri diversi.

    Ciao Weierstrass, complimenti sai riempire una matrice senza usare due cicli for. Comunque uso il metodo revove() perché oltre ad inserire l'elemento della lista nella matrice, lo devo anche cancellare. Così dice il testo dell'esercizio.
Devi accedere o registrarti per scrivere nel forum
12 risposte