Visualizzazione dei risultati da 1 a 9 su 9
  1. #1

    Problema con matrice di boolean

    Non so se ai moderatori vada bene questo titolo ma non so che inventarmi.

    Comunque data una matrice di boolean devo realizzare un metodo che calcola il numero di secoli
    necessari ad inondare la matrice.

    Mi spiego meglio, la matrice rappresenta una topografia. Le caselle false sono acqua. Le caselle
    true sono terra. Una spiaggia è una casella di terra (true) che confina con almeno un'area d'acqua (false).

    L'idea sarebbe questa:

    Un ciclo while che chiama un metodo che si occupa di inondare man mano le spiagge. Conto il numero
    di iterazioni e lo restituisco. Incollo il codice, ho un problema di ciclo infinito

    codice:
    public class Homework4RImpl extends Homework4R
    {
        public Homework4RImpl() {}
    
        class Elemento
        {
            private int i;
            private int j;
    
            public Elemento(int i, int j)
            {
                this.i = i;
                this.j = j;
            }
        }
        
        public int secoliInondazione(boolean[][] topografia)
        {
            boolean[][] copia = this.copia(topografia); //Evito di fare side effect su topografia
            int ris = 0;
            while(!tuttaAcqua(copia))
            {
                inonda(copia);
                ris++;
            }
            return ris;
        }
    
        private void inonda(boolean[][]topografia)
        {
            List<Elemento> spiagge = new LinkedList<Elemento>();
            
            for(int i=0; i<topografia.length; i++)
            {
            	for(int j=0; j<topografia[0].length; j++)
            	{
            		if(topografia[i][j] == true && isSpiaggia(topografia,i,j))
            		{
            			Elemento e = new Elemento(i,j);
            			spiagge.add(e);
            		}
            	}
            }
            
            for(int i=0; i<topografia.length; i++)
            {
            	for(int j=0; j<topografia[0].length; j++)
            	{
            		if(topografia[i][j] == true)
            		{
            			Elemento e = new Elemento(i,j);
            			if(spiagge.contains(e))
            			{
            				topografia[i][j] = false;
            			}
            		}
            	}
            }
        }
        
        private boolean isSpiaggia(boolean[][]topografia, int i, int j)
        {
            boolean[] confini = this.confiniBooleanVersion(topografia, i, j);
            
            if(confini[0] == false || confini[1] == false || confini[2] == false || confini[3] == false || confini[4] == false
                    || confini[5] == false || confini[6] == false || confini[7] == false)
            {
                return true;
            }
    
            else return false;
        }
    
        private boolean tuttaAcqua(boolean[][]topografia)
        {
            for(int i=0; i<topografia.length; i++)
            {
                for(int j=0; j<topografia[0].length; j++)
                {
                    if(topografia[i][j] == true)
                    {
                        return false;
                    }
                }
            }
            return true;
        }
    
         private boolean[][] copia(boolean[][]topografia)
        {
            int righe = topografia.length;
            int colonne = topografia[0].length;
            boolean[][] ris = new boolean[righe][colonne];
            for(int i=0; i<topografia.length; i++)
            {
                for(int j=0; j<topografia[0].length; j++)
                {
                    ris[i][j] = topografia[i][j];
                }
            }
            return ris;
        }
    
         private boolean[] confiniBooleanVersion(boolean[][]topografia, int i, int j)
        {
            boolean uno = topografia[i-1][j-1];
            boolean due = topografia[i-1][j];
            boolean tre = topografia[i-1][j+1];
            boolean quattro = topografia[i][j-1];
            boolean cinque = topografia[i][j+1];
            boolean sei = topografia[i+1][j-1];
            boolean sette = topografia[i+1][j];
            boolean otto = topografia[i+1][j+1];
            boolean[]arr = {uno,due,tre,quattro,cinque,sei,sette,otto};
            return arr;
        }
    }

  2. #2

    Re: Problema con matrice di boolean

    Originariamente inviato da Javino89
    ho un problema di ciclo infinito
    Credo che il problema è qui
    Originariamente inviato da Javino89
    codice:
       Elemento e = new Elemento(i,j);
       if(spiagge.contains(e))
       {
          topografia[i][j] = false;
       }
    perchè il metodo contains utilizza il metodo equals che la tua classe Elemento non ridefinisce.

    Quindi, nessuna cella viene settata a false ..

  3. #3
    Ah cavolo, quindi devo ridefinire equals? E gia che ci sono cambio la LinkedList con l'ArrayList..

  4. #4
    Originariamente inviato da Javino89
    quindi devo ridefinire equals?
    Si ..

    Poi fai attenzione al metodo confiniBooleanVersion:
    con i = j = 0 cade in eccezione.

  5. #5
    Si si per quello ho fatto in modo che la matrice venga scandita a partire da i e j = 1 fino a topografia.length-1 e topografia[0].length-1, tanto la prima ed ultima riga e la prima ed ultima colonna sono messi sempre a false. Comunque ho ridefinito equals in questo modo:

    codice:
    public boolean equals(Object x)
            {
            	Elemento e = (Elemento)x;
            	
            	return this.i == e.i && this.j == e.j;
            }
    E pare funzionare o.o Grazie

  6. #6
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,320
    Consiglio di ridefinire anche hashCode().... se un domani dovrai inserire questi oggetti in una HashMap (o altra struttura che utilizza la funzione di hash) ti ritroverai con lo stesso problema.


    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  7. #7
    Provo a chiedere consiglio anche per un altro metodo sempre della stessa classe. In sostanza devo contare quante isole ci sono nella matrice. Un'isola è un'area costituita da celle contigue di terra. Il metodo che ho scritto non funziona sempre, e quando sbaglia lo fa di poco, ma comunque sbaglia e non ne vengo a capo. Inoltre ciò che ho fatto mi sembra inefficente.

    L'idea che ho utilizzato è questa:

    Creo una lista di liste di oggetti elemento. Per ogni area di terra che trovo la inserisco nella
    lista di liste andando a controllare per ogni lista della lista se confina con qualcosa che ho già inserito. Oddio così è un po complesso da spiegare, metto il codice va.. xD

    codice:
    ...
    
    public int contaIsole(boolean[][] topografia)
        {
            List<List<Elemento>> isole = new ArrayList<List<Elemento>>();
            
            for(int i=0; i < topografia.length; i++)
            {
                for(int j=0; j < topografia[0].length; j++)
                {
                    if(topografia[i][j] == true)
                    {
                        Elemento e = new Elemento(i,j);
                        aggiungiElemento(isole,e,topografia);
                    }
                }
            }
            stampaIsole(isole);
            return isole.size();
        }
    
        private void aggiungiElemento(List<List<Elemento>> isole, Elemento e
                , boolean[][]topografia)
        {   
        	Iterator<List<Elemento>> it = isole.iterator();
            while(it.hasNext())
            {
                List<Elemento> isola = it.next();
                if(faParteDi(isola,e,topografia))
                {
                    isola.add(e);
                    return;
                }
            }
            //Arrivati a questo punto l'elemento non fa parte di alcuna isola già trovata, quindi
            //è una nuova isola
            List<Elemento> nuova_isola = new ArrayList<Elemento>();
            nuova_isola.add(e);
            isole.add(nuova_isola);
        }
    
        private boolean faParteDi(List<Elemento> isola, Elemento e,
                boolean[][]topografia)
        {
            for(int y=0; y<isola.size(); y++)
            {
                Elemento curr = isola.get(y);
                if(terreConfinanti(curr,e,topografia))
                {
                    return true;
                }
            }
            return false;
        }
    
        private boolean terreConfinanti(Elemento e1, Elemento e2,
                boolean[][]topografia)
        {
            int xe1 = e1.i;
            int ye1 = e1.j;
            int xe2 = e2.i;
            int ye2 = e2.j;
    
            Elemento[]confini_e1 = this.confini(topografia, xe1, ye1);
            
            for(int i=0; i<confini_e1.length; i++)
            {
                Elemento temp1 = confini_e1[i];
                int coord1 = temp1.i;
                int coord2 = temp1.j;
    
                if(coord1 == xe2 && coord2 == ye2)
                {
                    return true;
                }
            }
    
            return false;
        }
    ...

  8. #8
    Originariamente inviato da Javino89
    devo contare quante isole ci sono nella matrice. Un'isola è un'area costituita da celle contigue di terra. Il metodo che ho scritto non funziona sempre, e quando sbaglia lo fa di poco, ma comunque sbaglia e non ne vengo a capo. Inoltre ciò che ho fatto mi sembra inefficente.

    L'idea che ho utilizzato è questa:

    Creo una lista di liste di oggetti elemento. Per ogni area di terra che trovo la inserisco nella
    lista di liste andando a controllare per ogni lista della lista se confina con qualcosa che ho già inserito. Oddio così è un po complesso da spiegare, metto il codice va.. xD
    Ti conviene definire un dato astratto che gestisca le relazioni tra i vari nodi/celle, che dunque modella e rappresenti un'isola in maniera più astratta ed efficace.

  9. #9
    Mmmh si hai ragione. Però sono vincolato a tenere una sola classe dove far funzionare tutto. Ora come ora visto che ho scritto tutto quel codice che ha solo qualche bug mi conviene finirlo penso Se qualcuno ha voglia di vedere come elabora allego il resto del codice e 2 main:

    Classe 1:

    codice:
    /**
     * Questa classe deve essere implementata per poter risolvere l'homework
     * Si ricorda che il nome della classe deve essere Homework4RImpl e non deve essere
     */
    public abstract class Homework4R {
        /**
         * le sottoclassi dovranno avere un solo costruttore senza argomenti
         */
        public Homework4R() {
            if (getClass().getConstructors().length != 1) {
                throw new RuntimeException("ATTENZIONE!!! La sottoclasse deve avere solo il costrutture senza argomenti. Trovati " + getClass().getConstructors().length + " costruttori");
            }
            if (getClass().getConstructors()[0].getParameterTypes().length > 0)
                throw new RuntimeException("ATTENZIONE!!! La sottoclasse deve avere solo il costrutture senza argomenti. Trovato un costruttore con " + getClass().getConstructors().length + " argomenti");
            if (!getClass().getSimpleName().equals("Homework4RImpl") &&
                    !getClass().getSimpleName().equals("Homework4RImplSolver")) {
                throw new RuntimeException("ATTENZIONE!!! La sottoclasse deve avere nome Homework4RImpl");
            }
            if (getClass().getPackage() != null) {
                throw new RuntimeException("ATTENZIONE!!! La sottoclasse non deve appartenere ad alcun PACKAGE");
            }
        }
    
        /**
         * restituisce il numero di isole nel territorio
         *
         * @param topografia topografia
         * @return numero di isole
         */
        public abstract int contaIsole(boolean[][] topografia);
        
    
        /**
         * Il metodo calcola il numero minimo di secoli necessari ad inondare tutte le aree emerse, considerando
         * che ogni secolo vengono inondate tutte le spiagge.
         * @param topografia topografia
         * @return numero minimo di secoli necessari a far sc
         */
        public abstract int secoliInondazione(boolean[][] topografia);
    
        /**
         * restituisce il numero di celle che costituiscono la spiaggia piu' ampia di una qualche isola
         *
         * @param topografia topografia
         * @return numero di celle della spiaggia piu' ampia
         */
        public abstract int spiaggiaPiuAmpia(boolean[][] topografia);
    }
    Classe 2:

    codice:
    import java.util.*;
    
    public class Homework4RImpl extends Homework4R
    {
        public Homework4RImpl() {}
    
        class Elemento
        {
            private int i;
            private int j;
    
            public Elemento(int i, int j)
            {
                this.i = i;
                this.j = j;
            }
            
            public boolean equals(Object x)
            {
            	Elemento e = (Elemento)x;
            	
            	return this.i == e.i && this.j == e.j;
            }
        }
        
        /////////////////////////////////////////////
        
        public int contaIsole(boolean[][] topografia)
        {
            List<List<Elemento>> isole = new ArrayList<List<Elemento>>();
            
            for(int i=0; i < topografia.length; i++)
            {
                for(int j=0; j < topografia[0].length; j++)
                {
                    if(topografia[i][j] == true)
                    {
                        Elemento e = new Elemento(i,j);
                        aggiungiElemento(isole,e,topografia);
                    }
                }
            }
            stampaIsole(isole);
            return isole.size();
        }
    
        private void aggiungiElemento(List<List<Elemento>> isole, Elemento e
                , boolean[][]topografia)
        {   
        	Iterator<List<Elemento>> it = isole.iterator();
            while(it.hasNext())
            {
                List<Elemento> isola = it.next();
                if(faParteDi(isola,e,topografia))
                {
                    isola.add(e);
                    return;
                }
            }
            //Arrivati a questo punto l'elemento non fa parte di alcuna isola già trovata, quindi
            //è una nuova isola
            List<Elemento> nuova_isola = new ArrayList<Elemento>();
            nuova_isola.add(e);
            isole.add(nuova_isola);
        }
    
        private boolean faParteDi(List<Elemento> isola, Elemento e,
                boolean[][]topografia)
        {
            for(int y=0; y<isola.size(); y++)
            {
                Elemento curr = isola.get(y);
                if(terreConfinanti(curr,e,topografia))
                {
                    return true;
                }
            }
            return false;
        }
    
        private boolean terreConfinanti(Elemento e1, Elemento e2,
                boolean[][]topografia)
        {
            int xe1 = e1.i;
            int ye1 = e1.j;
            int xe2 = e2.i;
            int ye2 = e2.j;
    
            Elemento[]confini_e1 = this.confini(topografia, xe1, ye1);
            
            for(int i=0; i<confini_e1.length; i++)
            {
                Elemento temp1 = confini_e1[i];
                int coord1 = temp1.i;
                int coord2 = temp1.j;
    
                if(coord1 == xe2 && coord2 == ye2)
                {
                    return true;
                }
            }
    
            return false;
        }
        
        ////////////////////////////////////////////////////
        
        public int secoliInondazione(boolean[][] topografia)
        {
            boolean[][] copia = this.copia(topografia); //Evito di fare side effect su topografia
            int ris = 0;
            while(!tuttaAcqua(copia))
            {
                inonda(copia);
                ris++;
            }
            return ris;
        }
    
        private void inonda(boolean[][]topografia)
        {
            List<Elemento> spiagge = new ArrayList<Elemento>();
            
            for(int i=1; i<topografia.length-1; i++)
            {
            	for(int j=1; j<topografia[0].length-1; j++)
            	{
            		if(topografia[i][j] == true && isSpiaggia(topografia,i,j))
            		{
            			spiagge.add(new Elemento(i,j));
            		}
            	}
            }
            
            for(int i=1; i<topografia.length-1; i++)
            {
            	for(int j=1; j<topografia[0].length-1; j++)
            	{
            		if(topografia[i][j] == true)
            		{
            			Elemento e = new Elemento(i,j);
            			if(spiagge.contains(e))
            			{
            				topografia[i][j] = false;
            			}
            		}
            	}
            }
        }
        
        private boolean isSpiaggia(boolean[][]topografia, int i, int j)
        {
            boolean[] confini = this.confiniBooleanVersion(topografia, i, j);
    
            if(confini[0] == false || confini[1] == false || confini[2] == false || confini[3] == false || confini[4] == false
                    || confini[5] == false || confini[6] == false || confini[7] == false)
            {
                return true;
            }
            
            return false;
        }
    
        private boolean tuttaAcqua(boolean[][]topografia)
        {
            for(int i=0; i<topografia.length; i++)
            {
                for(int j=0; j<topografia[0].length; j++)
                {
                    if(topografia[i][j] == true)
                    {
                        return false;
                    }
                }
            }
            return true;
        }
        
        ///////////////////////////////////////////////////
        
        public int spiaggiaPiuAmpia(boolean[][] topografia)
        {
            return 0;
        }
        
        ////////////////////////////////////////////////
    
        private boolean[][] copia(boolean[][]topografia)
        {
            int righe = topografia.length;
            int colonne = topografia[0].length;
            boolean[][] ris = new boolean[righe][colonne];
            for(int i=0; i<topografia.length; i++)
            {
                for(int j=0; j<topografia[0].length; j++)
                {
                    ris[i][j] = topografia[i][j];
                }
            }
            return ris;
        }
    
        private Elemento[] confini(boolean[][]topografia,int i,int j)
        {
            Elemento uno = new Elemento(i-1,j-1);
            Elemento due = new Elemento(i-1,j);
            Elemento tre = new Elemento(i-1,j+1);
            Elemento quattro = new Elemento(i,j-1);
            Elemento cinque = new Elemento(i,j+1);
            Elemento sei = new Elemento(i+1,j-1);
            Elemento sette = new Elemento(i+1,j);
            Elemento otto = new Elemento(i+1,j+1);
            Elemento[]arr = {uno,due,tre,quattro,cinque,sei,sette,otto};
            return arr;
        }
    
        private boolean[] confiniBooleanVersion(boolean[][]topografia, int i, int j)
        {
            boolean uno = topografia[i-1][j-1];
            boolean due = topografia[i-1][j];
            boolean tre = topografia[i-1][j+1];
            boolean quattro = topografia[i][j-1];
            boolean cinque = topografia[i][j+1];
            boolean sei = topografia[i+1][j-1];
            boolean sette = topografia[i+1][j];
            boolean otto = topografia[i+1][j+1];
            boolean[]arr = {uno,due,tre,quattro,cinque,sei,sette,otto};
            return arr;
        }
    
        public static void stampa(boolean[][] topografia)
        {
            for(int i=0; i<topografia.length; i++)
            {
                for(int j=0; j<topografia[0].length; j++)
                {
                    if(topografia[i][j] == true)
                    {
                        System.out.print("#");
                    }
                    else
                        System.out.print(".");
                }
                System.out.println();
            }
        }
        
        private void stampaIsole(List<List<Elemento>> isole)
        {
            Iterator<List<Elemento>> it = isole.iterator();
            while(it.hasNext())
            {
                List<Elemento> curr = it.next();
                for(int i = 0; i < curr.size(); i++)
                {
                    Elemento e = curr.get(i);
                    System.out.print("(" + e.i + "," + e.j + ")" + "");
                }
                System.out.println();
                System.out.println("-");
            }
        }
    }
    Main 1:

    codice:
    public class Test
    {
        public static void main(String[] args)
        {
            boolean a = false;
            boolean t = true;
            double d = Math.random()*30;
            int dim = (int)d;
            boolean[][] topografia = new boolean[dim][dim];
            
            for(int i=1; i < topografia.length-1; i++)
            {
                for(int j=1; j< topografia[i].length-1; j++)
                {
                    double r = Math.random()*2;
                    int a_t = (int)r;
                    if(a_t == 0)
                    {
                        topografia[i][j] = a;
                    }
                    else
                    {
                        double x = Math.random()*2;
                        int d_m = (int)x;
                        if(d_m == 0)
                        {
                            topografia[i][j] = t;
                        }
                        else topografia[i][j] = a;
                    }
                }
            }
    
            System.out.println("Questa è la topografia");
            System.out.println();
    
            stampa(topografia);
            System.out.println();
            
            Homework4R h = new Homework4RImpl();
    
            int numero_isole = h.contaIsole(topografia);
            System.out.println();
            System.out.println("Il numero di isole della topografia sono: " + numero_isole);
            System.out.println();
    
            int secoli_inondazione = h.secoliInondazione(topografia);
            System.out.println("Il numero di secoli necessari ad inondare tutta la topografia sono: " + secoli_inondazione);
            System.out.println();
    
            int max_spiaggia = h.spiaggiaPiuAmpia(topografia);
            System.out.println("La spiaggia più ampia è composta da: " + max_spiaggia + " celle");
            System.out.println();
        }
    
        public static void stampa(boolean[][] topografia)
        {
            for(int i=0; i<topografia.length; i++)
            {
                for(int j=0; j<topografia[0].length; j++)
                {
                    if(topografia[i][j] == true)
                    {
                        System.out.print("#");
                    }
                    else
                        System.out.print(".");
                }
                System.out.println();
            }
        }
    }

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.