Duplicati in array bidimensionale

di il
12 risposte

Duplicati in array bidimensionale

Ciao ragazzi,
devo creare un programma Java che permetta di giocare al Sudoku.
Devo creare un array bidimensionale 9x9 e devo cercare al suo interno la presenza di numeri duplicati (secondo le regole del gioco).

Ho implementato questo metodo:
public void verificaGioco() {
		int riga[]=new int[9];
		
		for(int i=0;i<scacchiera.length;i++) {
			
			for(int j=0;j<=scacchiera[0].length-1;j++) {
				riga[i]=scacchiera[i][j];
				System.out.print(riga[i]+" ");
				if(riga[i]==scacchiera[i][j]) {
					System.out.print("ci sono duplicati ");
				}else {
					System.out.print("non ci sono duplicati ");
				}
				
			}
			System.out.println();
			
			
		}

	}
ma non riesco mai ad evitare di includere il primo elemento dell'array dal controllo di se stesso.
come faccio ad evitarlo?
grazie mille a tutti

12 Risposte

  • Re: Duplicati in array bidimensionale

    Non credo quello sia il modo giusto per verificare se all'interno di un array multidimensionale ci siano duplicati. Sembra che tu stia cercando duplicati iterando riga per riga e cercando duplicati nella riga corrente ma come faresti nel caso ci siano numeri duplicati in righe differenti? Esempio :

    [3, 0, 8, 4]
    [2, 4, 5, 7]
    [9, 2, 6, 3]
    [0, 3, 1, 2]

    Ogni riga di questa matrice non contiene duplicati, ma ci sono considerando righe differenti : 3,0,4,2.Lo stesso discorso varrebbe considerando solo colonna per colonna. Una soluzione potrebbe essere usare una Map<Integer,Integer> in cui la key la utilizzi per memorizzare il valore, e value lo utilizzi per memorizzare quante volte il valore si presenta in matrice.
    Iterando poi le entries nella Map puoi scoprire quali valori sono duplicati (quelli che avranno value > 1).
  • Re: Duplicati in array bidimensionale

    Considera che non posso usare le map,ma solo gli array o il metodo Integer.toString.
    Questo passaggio che ho pubblicato era riferito solamente alla ricerca per riga,poi ovviamente avrei implementato anche quello per colonna.
    Per quanto riguarda la matrice che hai scritto, secondo le regole del Sudoku, i duplicati che mi interessa trovare devono riguardare solamente la prima riga e la prima colonna e cosi via( ogni riga deve avere un numero da 1 a 9 senza ripetizioni e ogni colonna deve avere un numero da 1 a 9 senza ripetizioni)
  • Re: Duplicati in array bidimensionale

    Ok
    
        static boolean containsDuplicate(int[][] tmp) {
            
            
            for (int i = 0; i < tmp.length; i++) {
                
                int first = tmp[i][0];
                for (int j = i+1; j < tmp[0].length; j++) {
                    if(first == tmp[i][j]) {
                        return true;
                    }
                }
            }
            
            for (int i = 0; i < tmp.length; i++) {
                
                int first = tmp[0][i];
                for (int j = i+1; j < tmp[0].length; j++) {
                    if(first == tmp[j][i]) {
                        return true;
                    }
                }
            }
            
            
            return false;
        }
    
  • Re: Duplicati in array bidimensionale

    A ok quindi la variabile di appoggio first la devo cambiare solo una volta ogni fine riga e colonna
  • Re: Duplicati in array bidimensionale

    Nigy ha scritto:


    A ok quindi la variabile di appoggio first la devo cambiare solo una volta ogni fine riga e colonna
    Si praticamente quando controlli le righe, inizializzi first con il primo elemento della riga corrente, quindi con il for loop interno va ad iterare i restanti elementi nella riga partendo dal secondo in poi (i+1). Stesso concetto per le colonne, partiamo sempre da riga 0 e colonna corrente (quindi primo elemento della colonna partendo dall'alto)
  • Re: Duplicati in array bidimensionale

    In pratica per ogni riga e per ogni colonna,il confronto dei vari elementi di tutta una riga o colonna viene sempre fatto solo con il primo di quella riga o colonna che sia
  • Re: Duplicati in array bidimensionale

    Hai ragione cavoli stavo considerando solo il primo elemento, array multidimensionali possono essere piuttosto confusionali. Ho modificato la soluzione, non e' bellissima da vedere ma dovrebbe funzionare :
    
        static boolean containsDuplicate(int[][] tmp) {
    
            for (int i = 0; i < tmp[0].length; i++) {
                
                int[] curr = tmp[i];
                for (int j = 0; j < curr.length; j++) {
                    for (int j2 = j+1; j2 < curr.length; j2++) {
                        if(tmp[i][j] == tmp[i][j2]) {
                            return true;
                        }
                    }
                }
            }
            
            for (int i = 0; i < tmp.length; i++) {
                
                int[] curr = new int[tmp.length];
                //retrieve column
                for (int j = 0; j < curr.length; j++) {
                    curr[j] = tmp[j][i];
                }
                
                for (int j = 0; j < curr.length; j++) {
                    for (int j2 = j+1; j2 < curr.length; j2++) {
                        if(curr[j] == curr[j2]) {
                            return true;
                        }
                    }
                }
    
            }
            
            
            return false;
        }
    
  • Re: Duplicati in array bidimensionale

    Qui una versione più efficiente, ma decisamente più complessa da capire.
    Aiuta a capire diverse sfaccettature della logica booleana e del linguaggio.
    (soprattutto ci si deve chiedere perchè non funziona più se si inverte il controllo delle righe e delle colonne )

    Ho incluso anche un Sudoku di test per fare delle prove...
    
    public class Sudoku {
       private static boolean verifica(int[][] mat) {
          boolean[] test = new boolean[10];
    
          // Verifica righe
          for(int riga=0; riga<mat.length; riga++) {
             for(int colonna=0; colonna<mat[riga].length; colonna++) {
                if (((riga % 2) == 0) != (test[mat[riga][colonna]-1] = !test[mat[riga][colonna]-1])) return false;
             }
          }
    
          // Verifica colonne
          for(int colonna=0; colonna<mat[0].length; colonna++) {
             for(int riga=0; riga<mat.length; riga++) {
                if (((colonna % 2) == 0) == (test[mat[riga][colonna]-1] = !test[mat[riga][colonna]-1])) return false;
             }
          }
    
          return true;
       }
    
       public static void main(String[] args) {
          int[][] mat = {{4,3,5,2,6,9,7,8,1},
                         {6,8,2,5,7,1,4,9,3},
                         {1,9,7,8,3,4,5,6,2},
                         {8,2,6,1,9,5,3,4,7},
                         {3,7,4,6,8,2,9,1,5},
                         {9,5,1,7,4,3,6,2,8},
                         {5,1,9,3,2,6,8,7,4},
                         {2,4,8,9,5,7,1,3,6},
                         {7,6,3,4,1,8,2,5,9}};
    
          if ( verifica(mat) ) {
             System.out.println("Sudoku corretto");
          } else {
             System.out.println("Sudoku NON corretto");
          }
       }
    }
    
  • Re: Duplicati in array bidimensionale

    Leleft
    il tuo codice mi produce un out of bound forse perché sottrai 1 dal conteggio degli elementi dell'array nei due cicli.
    magicsign
    sto facendo varie prove con il tuo codice, per ora sto provando a farmi stampare se ci sono o meno i duplicati per vedere se tutto funziona correttamente, ma credo che il codice produca dei duplicati quando va a fare il controllo, ti spiego:
    questo è il mio array:

    scacchiera {1,2,3,4,9,7,8,6,5}
    {4,0,0,0,0,0,0,0,0}
    {6,0,0,0,0,0,0,0,0}
    {3,0,0,0,0,0,0,0,0}
    {2,0,0,0,0,0,0,0,0}
    {9,0,0,0,0,0,0,0,0}
    {8,0,0,0,0,0,0,0,0}
    {7,0,0,0,0,0,0,0,0}
    {5,0,0,0,0,0,0,0,0}
    i valori dovranno essere inseriti da tastiera, quindi gli zeri rappresentano le caselle vuote dello schema del sudoku

    Eseguendo il codice
    public void verificaGioco() {


    for(int i=0;i<scacchiera[0].length;i++) {

    int riga[]=scacchiera;
    for(int j=0;j<riga.length;j++) {

    for(int j2=j+1;j2<riga.length;j2++) {
    System.out.print(riga[j2]);
    if(scacchiera[j]==scacchiera[j2]) {

    System.out.print("d ");
    }else {

    System.out.print("nd ");
    }
    }
    }
    System.out.println();
    }

    for (int i = 0; i < scacchiera.length; i++) {

    int[] colonna = new int[scacchiera.length];
    //retrieve column
    for (int j = 0; j < colonna.length; j++) {
    colonna[j] = scacchiera[j];
    }

    for (int j = 0; j < colonna.length; j++) {

    for (int j2 = j+1; j2 < colonna.length; j2++) {
    //System.out.print(colonna[j2-1]);
    if(colonna[j] == colonna[j2]) {

    System.out.print("d ");
    }else {

    System.out.print("nd ");
    }
    }

    }


    }
    }


    mi tira fuori questo output dove la d sta duplicati e nd sta per non duplicati:
    2nd 3nd 4nd 9nd 7nd 8nd 6nd 5nd 3nd 4nd 9nd 7nd 8nd 6nd 5nd 4nd 9nd 7nd 8nd 6nd 5nd 9nd 7nd 8nd 6nd 5nd 7nd 8nd 6nd 5nd 8nd 6nd 5nd 6nd 5nd 5nd
    0nd 0nd 0nd 0nd 0nd 0nd 0nd 0nd 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d
    0nd 0nd 0nd 0nd 0nd 0nd 0nd 0nd 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d
    0nd 0nd 0nd 0nd 0nd 0nd 0nd 0nd 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d
    0nd 0nd 0nd 0nd 0nd 0nd 0nd 0nd 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d
    0nd 0nd 0nd 0nd 0nd 0nd 0nd 0nd 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d
    0nd 0nd 0nd 0nd 0nd 0nd 0nd 0nd 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d
    0nd 0nd 0nd 0nd 0nd 0nd 0nd 0nd 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d
    0nd 0nd 0nd 0nd 0nd 0nd 0nd 0nd 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d
    nd nd nd nd nd nd nd nd nd nd nd nd nd nd nd nd nd nd nd nd nd nd nd nd nd nd nd nd nd nd nd nd nd nd nd nd nd nd nd nd nd nd nd nd d d d d d d d d d d d d d d d d d d d d d d d d d d d d nd nd nd nd nd nd nd nd d d d d d d d d d d d d d d d d d d d d d d d d d d d d nd nd nd nd nd nd nd nd d d d d d d d d d d d d d d d d d d d d d d d d d d d d nd nd nd nd nd nd nd nd d d d d d d d d d d d d d d d d d d d d d d d d d d d d nd nd nd nd nd nd nd nd d d d d d d d d d d d d d d d d d d d d d d d d d d d d nd nd nd nd nd nd nd nd d d d d d d d d d d d d d d d d d d d d d d d d d d d d nd nd nd nd nd nd nd nd d d d d d d d d d d d d d d d d d d d d d d d d d d d d nd nd nd nd nd nd nd nd d d d d d d d d d d d d d d d d d d d d d d d d d d d d


    o ho inserito male io la syso (ma ho fatto varie prove e il risultato è più o meno lo stesso) oppure c'è ancora qualcosa che ci sfugge
  • Re: Duplicati in array bidimensionale

    Quel codice non produce proprio nessuna eccezione (forse l'hai copiato male: preso, copiato, incollato, compilato ed eseguito).
    E non fa alcun conteggio: sfrutta solamente la logica booleana.
    Visto il resto della tua risposta, allora sì: va tenuto conto dello ZERO. Il codice che ho postato io verifica uno schema GIA' compilato completamente.

    Ciao.
  • Re: Duplicati in array bidimensionale

    Nigy il codice che ti ho postato non modifica l'array multidimensionale preso come parametro, ti consiglio di rivedere il tuo adattamento, saluti
  • Re: Duplicati in array bidimensionale

    Ciao ragazzi,
    grazie ai vostri consigli sono riuscito a risolvere il problema dei duplicati in un array bidimensionale
    Il problema è che non riesco a capire che tipo di logica vuole farmi usare il testo per risolvere questo esercizio per la creazione del gioco del Sudoku.

    Il codice che ho implementato è questo:
    
    public class Sudoku {
    	
    	private int scacchiera[][]=new int[9][9];
    	private boolean inizio[][]=new boolean[9][9];
    	
    	
    	public Sudoku() {
    		for(int i=0;i<scacchiera.length;i++) {
    			for(int j=0;j<scacchiera[0].length;j++) {
    				scacchiera[i][j]=0;
    			}
    		}
    		
    		for(int i=0;i<inizio.length;i++) {
    			for(int j=0;j<inizio[0].length;j++) {
    				inizio[i][j]=false;
    			}
    		}
    	}
    	
    	public void aggiungiIniziali(int riga, int colonna, int valore) {
    		scacchiera[riga][colonna]=valore;
    		inizio[riga][colonna]=true;
    	}
    	
    	public void aggiungiMossa(int riga,int colonna,int valore) {
    		
    		if(getValoriValidi(riga, colonna)[colonna]==true) {
    			scacchiera[riga][colonna]=valore;
    			if(!verificaGioco()) {
    				System.out.println("Hai gia inserito il "+getValoreIn(riga, colonna)+ " in questa riga o colonna");
    				System.out.println("inserisci un altro valore");
    				scacchiera[riga][colonna]=0;
    			}
    			
    		}else {
    			System.out.println("Non puoi modificare il valore di questa cella.");
    		}
    		
    	}
    	
    	public boolean verificaGioco() {
    		
    		int riga[]=new int[9];
    		int colonna[]=new int[9];
    		
    		for(int i=0;i<scacchiera.length;i++) {
    			for(int j=0;j<scacchiera[0].length;j++) {
    				
    				 riga[i]=scacchiera[i][j];
    				 colonna[i]=scacchiera[j][i];
    				
    				 for(int j2=j+1;j2<riga.length;j2++) {	
    					 if(riga[i]==0 || colonna[i]==0) {
    						 continue;
    					 }
    					 
    					 if( (riga[i]==scacchiera[i][j2]) || (colonna[i]==scacchiera[j2][i]) ) {
    						 return false;
    					 }
    				 }
    			}
    			
    		}
    		
    		return true;
    		
    	}
    	
    	private int getValoreIn(int riga,int colonna) {
    		return scacchiera[riga][colonna];
    	}
    	
    	private boolean[] getValoriValidi(int riga, int colonna) {
    		boolean array[]=new boolean[9];
    		
    		if(inizio[riga][colonna]==false && verificaGioco()) {
    			array[colonna]=true;
    		}
    		
    		return array;
    	}
    	
    	public boolean pieno() {
    		
    		for(int i=0;i<scacchiera.length;i++) {
    			for(int j=0;j<scacchiera[0].length;j++) {
    				if(scacchiera[i][j]==0) {
    					return false;
    				}
    			}
    		}
    		return true;
    	}
    	
    	public void reset() {
    		
    		for(int i=0;i<inizio.length;i++) {
    			for(int j=0;j<inizio[0].length;j++) {
    				if(inizio[i][j]==false) {
    					scacchiera[i][j]=0;
    				}
    			}
    		}
    	}
    	
    	public void String() {
    		for(int i=0;i<scacchiera.length;i++) {
    			for(int j=0;j<scacchiera[0].length;j++) {
    				if(scacchiera[i][j]==0) {
    				System.out.print(" "+" ");
    				}else {
    					System.out.print(scacchiera[i][j]+" ");
    					
    				}
    			}
    			System.out.println();
    		}
    	}
    
    }
    
    scacchiera è l'array dove l'utente dovrà inserire prima i valori dello schema di partenza, quelli che non andranno modificati, e poi ci dovrà inserire le cifrerà inserire nelle celle cuore per risolvere lo schema.
    Inizio invece è l'array che specifica quali sono i valori che non possono essere cambiati all'interno dell'array scacchiera.
    Tra gli altri metodi mi viene chiesto di creare il metodo getValoriValidi(riga, colonna) che restituisce un array monodimensionale di nove valori booleani, ognuno dei quali corrisponde ad una cifra e risulta vero se la cifra può essere posta alla posizione specificata da riga e colonna senza violare le regole del gioco.
    Credo di aver implementato bene il metodo secondo le regole del gioco, ma non riesco a capire in che modo vuole farmelo utilizzare (credo) nel metodo aggiungiMossa(riga, colonna, valore) per poter controllare che i valori inseriti siano corretti
Devi accedere o registrarti per scrivere nel forum
12 risposte