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

    Controllare se una matrice ha "coppie" diverse!

    E' tutto oggi che esco pazzo

    Ho bisogno di un algoritmo che mi controlli se in una matrice ci sono coppie di numeri uguali.

    Mi spiego meglio: ho una matrice con x righe, ognuna delle quali hanno SOLO numeri diversi.

    Ho bisogno di controllare che le coppie siano diverse. Ad esempio se la matrice è formata dai numeri: 1,2,3,4,5,6,7,8 sarà formata dalle coppie 1-2,3-4,5-6,7-8 e queste coppie devono essere uniche in tutte le righe.

    Ho già letto dell'algoritmo di berger ma cerco qualcosa che sia realizzato con le cose che so fare io (molte cose ancora non le ho fatte).

    Stavo pensando ad un algoritmo del genere:
    codice:
    public static boolean verificaCoppie(int[][]matrice2){
    
            boolean controllo=false;
    
        	for(int i=0;i<matrice2.length-1;i++){
    
        		for(int j=0;j<matrice2[0].length;j++){
    
                        for(int x=0;x<matrice2.length-1;x++){
    
                            for(int y=0;y<matrice2[0].length;y++){
    
                                if(i!=x && j!=y && matrice2[i][j]==matrice2[x][y])){
                                    if(matrice2[i+1][j]==matrice2[x+1][j]){
                                        return false;
                                    }
                                    
                                }
                                 else{
                                        controllo=true;
                                         }
    
                                y++;
                            }
                        }
    
                        j++;
        		}
    
        	}
    
        	return controllo;
        }
    Ma ogni tanto mi fa qualche errore..sono sicuro che sia quasi arrivato alla conclusione ma mi manca qualcosina

  2. #2
    Utente di HTML.it L'avatar di desa
    Registrato dal
    Oct 2008
    Messaggi
    569
    L'algoritmo non è immediato da comprendere, ma se ho capito bene...

    codice:
    for (int j = 0; j < matrice2[0].length; j++)
    lo trasformerei in

    codice:
    for (int j = 0; j < matrice2[0].length; j+=2)
    eliminando il j++ alla fine (stessa cosa per la variabile "y").

    codice:
    for (int x = 0; x < matrice2.length - 1; x++)
    puoi modificarlo in

    codice:
    for (int x = i + 1; x < matrice2.length; x++)
    visto che, se una riga è unica rispetto a tutte quelle che la seguono, sarà vero anche il viceversa.

    C'è una parentesi tonda di troppo in

    codice:
    if (i != x && j != y && matrice2[i][j] == matrice2[x][y]))
    In ogni caso non mi torna la parte centrale del codice... a occhio io la farei così (prova a pensarci e dimmi cosa ne pensi)

    codice:
    if (matrice2[i][j] == matrice2[x][y] && matrice2[i][j + 1] == matrice2[x][j + 1])
    {
      return false;
    }
    Eliminerei inoltre la variabile "controllo": se raggiungi la fine del ciclo significa che non ci sono coppie duplicate e quindi puoi fare un return true

  3. #3
    grazie mille desa per i tuoi preziosi consigli

    Ho modificato l'algoritmo come segue:
    codice:
    //controlla che gli accoppiamenti siano tutti diversi
        public static boolean verificaCoppie(int[][]matrice2){
    
    
        	for(int i=0;i<matrice2.length-1;i++){
    
        		for(int j=0;j<matrice2[0].length;j+=2){
    
                        for(int x=i+1;x<matrice2.length-1;x++){
    
                            for(int y=0;y<matrice2[0].length;y+=2){
    
                                if(i!=x && j!=y && matrice2[i][j]==matrice2[x][y]){
    
                                    if (matrice2[i][j] == matrice2[x][y] && matrice2[i][j + 1] == matrice2[x][j + 1])
                                        
                                        {
                                             return false;
                                    }
                                    
                                }
                                
                            }
                        }
    
        		}
    
        	}
    
        	return true;
        }
    però ogni tanto mi da ancora qualche errore. Non sempre, però ogni tanto si quindi credo ci sia ancora qualcosina che non va

    sto eseguendo più volte il programma per capire dove fa l'errore e con che "logica" capita. Ti posto l'intero programma cosi magari puoi provare pure tu

    codice:
    public class calendario{
    
        public static void main(String[] args){
    
            // creo la matrice con il numero di righe e colonne definite
    
            int matrice[][] = new int[5][8];
    
            do{
    
            matrice=creaMatrice(matrice);
    
            } while(verificaCoppie(matrice)==false);
    
           for(int i=0;i<matrice.length;i++){
    
               for(int j=0;j<matrice[0].length;j++){
    
                  System.out.print("["+matrice[i][j]+"] ");
               }
    
               System.out.println();
           }
            
        }
    
    
        public static int[][]creaMatrice(int[][]matrice){
    
        // cliclo l'array bidimensionale
    
            for (int i = 0; i < matrice.length; i++) {
    
    
                for (int j = 0; j < matrice[0].length; j++) {
    
    
                	// Inizio controllo numeri diversi per riga
    
                	boolean unico;
    
                	do
    
                	{
                	  unico = true;
    
                	  matrice[i][j] = (int)(Math.random()*8)+1;
    
                	  for (int x = 0; x < j; x++)
    
                	  {
                	    if (matrice[i][j] == matrice[i][x])
    
                	    {
    
                	      unico = false;
    
                	    }
    
                	  }
    
                	} while (!unico);
    
                }
    
                }
    
            return matrice;
    
        }
    
        //controlla che gli accoppiamenti siano tutti diversi
        public static boolean verificaCoppie(int[][]matrice2){
    
    
        	for(int i=0;i<matrice2.length-1;i++){
    
        		for(int j=0;j<matrice2[0].length;j+=2){
    
                        for(int x=i+1;x<matrice2.length-1;x++){
    
                            for(int y=0;y<matrice2[0].length;y+=2){
    
                                if(i!=x && j!=y && matrice2[i][j]==matrice2[x][y]){
    
                                    if (matrice2[i][j] == matrice2[x][y] && matrice2[i][j + 1] == matrice2[x][j + 1])
    
                                        {
                                             return false;
                                    }
                                    
                                }
                                
                            }
                        }
    
        		}
    
        	}
    
        	return true;
        }
    }

  4. #4
    Utente di HTML.it L'avatar di desa
    Registrato dal
    Oct 2008
    Messaggi
    569
    Di che tipo di errori parli? Eccezioni, oppure mancati riconoscimenti di coppie ripetute? Nel primo caso prova a postare i messaggi di errore e vediamo dove sono causate.

    Attenzione però: io intendevo dire che sostituirei l'intera parte centrale del codice (a che serve il primo if? "i" non sarà mai uguale a "x", ed è lecito che "j" sia uguale a "y"). Te lo riscrivo qui di seguito:

    codice:
    . . . . .
    for(int y = 0; y < matrice2[0].length; y += 2)
    {
      if (matrice2[i][j] == matrice2[x][y] && matrice2[i][j + 1] == matrice2[x][y + 1])
      {
        return false;
      }
    }
    . . . . .
    Ho corretto un errore (c'era una "j" al posto di una "y").
    Ti segnalo inoltre che, nel caso tu consideri "uguali" le due coppie ordinate rispettivamente "A - B" e "B - A" (come in
    1 2 3 4 5 6
    . . .
    2 1 3 5 4 6
    ) devi definire l'if di cui sopra come

    codice:
    if (matrice2[i][j] == matrice2[x][y] && matrice2[i][j + 1] == matrice2[x][y + 1] || matrice2[i][j] == matrice2[x][y + 1] && matrice2[i][j + 1] == matrice2[x][y])

  5. #5
    Errori nel senso che ogni tanto mi spunta fuori una coppia uguale!

    Allora ho eliminato il primo if che mi hai fatto notare ed ho modificato il secondo if.
    Ora l'algoritmo è:

    codice:
    //controlla che gli accoppiamenti siano tutti diversi
        public static boolean verificaCoppie(int[][]matrice2){
    
    
        	for(int i=0;i<matrice2.length-1;i++){
    
        		for(int j=0;j<matrice2[0].length;j+=2){
    
                        for(int x=i+1;x<matrice2.length-1;x++){
    
                            for(int y=0;y<matrice2[0].length;y+=2){
    
                                     if (matrice2[i][j] == matrice2[x][y] && matrice2[i][j + 1] == matrice2[x][y + 1] || matrice2[i][j] == matrice2[x][y + 1] && matrice2[i][j + 1] == matrice2[x][y])
    
                                        {
                                             return false;
                                    }
                                
                            }
                            
                        }
    
        		}
    
        	}
    
        	return true;
        }
    Ad esempio, copio e incollo dalla console:

    codice:
    [7] [4] [8] [6] [3] [2] [5] [1] 
    [2] [1] [4] [3] [6] [7] [5] [8] 
    [4] [5] [1] [3] [8] [7] [2] [6] 
    [7] [5] [2] [4] [6] [3] [1] [8] 
    [4] [6] [8] [7] [2] [3] [1] [5]
    In questo caso nella prima riga c'è 3-2 e nell'ultima riga c'è 2-3

    Oppure
    codice:
    [4] [5] [7] [6] [8] [2] [1] [3] 
    [3] [4] [6] [5] [8] [7] [2] [1] 
    [7] [2] [5] [3] [1] [6] [8] [4] 
    [4] [1] [6] [2] [8] [3] [5] [7] 
    [4] [5] [6] [7] [3] [2] [8] [1]
    in questo caso nella prima riga c'è 7-6 e nell'ultima 6-7

    Per trovare questi due errori ho lanciato il programma SETTE VOLTE, quindi nelle altre 5 volte l'algoritmo ha funzionato bene

    L'errore PARE essere nell'ultima riga dove forse non esegue il controllo?

  6. #6
    Utente di HTML.it L'avatar di desa
    Registrato dal
    Oct 2008
    Messaggi
    569
    Sì, probabilmente è quello (te l'avevo segnalato in un post precedente! )...
    Per ogni "i" che cicla da 0 a length - 1 (escluso), "x" deve ciclare da 1 a length - 1 (incluso). Così com'è ora l'ultima riga non viene mai considerata. Dovrebbe essere sufficiente correggere il for sulla "x" con

    codice:
    for(int x=i+1;x<matrice2.length;x++)

  7. #7
    cavolo desa mi deve essere sfuggito quel suggerimento che mi avevi dato

    Cmq ora funziona bene, anzi benissimo

    Lascio il codice sul forum se dovesse un giorno servire a qualcuno

    codice:
    public class calendario{
    
        public static void main(String[] args){
    
            // creo la matrice con il numero di righe e colonne definite
    
            int matrice[][] = new int[5][8];
    
            int contatore=0;
    
            do{
    
            matrice=creaMatrice(matrice);
    
            contatore++;
    
            } while(verificaCoppie(matrice)==false);
    
           for(int i=0;i<matrice.length;i++){
    
               for(int j=0;j<matrice[0].length;j++){
    
                  System.out.print("["+matrice[i][j]+"] ");
               }
    
               System.out.println();
           }
    
            System.out.println("\nSono stati ben provati "+contatore+" accoppiamenti");
            
        }
    
    
        public static int[][]creaMatrice(int[][]matrice){
    
        // cliclo l'array bidimensionale
    
            for (int i = 0; i < matrice.length; i++) {
    
    
                for (int j = 0; j < matrice[0].length; j++) {
    
    
                	// Inizio controllo numeri diversi per riga
    
                	boolean unico;
    
                	do
    
                	{
                	  unico = true;
    
                	  matrice[i][j] = (int)(Math.random()*8)+1;
    
                	  for (int x = 0; x < j; x++)
    
                	  {
                	    if (matrice[i][j] == matrice[i][x])
    
                	    {
    
                	      unico = false;
    
                	    }
    
                	  }
    
                	} while (!unico);
    
                }
    
                }
    
            return matrice;
    
        }
    
        //controlla che gli accoppiamenti siano tutti diversi
        public static boolean verificaCoppie(int[][]matrice2){
    
    
        	for(int i=0;i<matrice2.length-1;i++){
    
        		for(int j=0;j<matrice2[0].length;j+=2){
    
                        for(int x=i+1;x<matrice2.length;x++){
    
                            for(int y=0;y<matrice2[0].length;y+=2){
    
                                     if (matrice2[i][j] == matrice2[x][y] && matrice2[i][j + 1] == matrice2[x][y + 1] || matrice2[i][j] == matrice2[x][y + 1] && matrice2[i][j + 1] == matrice2[x][y])
    
                                        {
                                             return false;
                                    }
                                
                            }
    
                        }
    
        		}
    
        	}
    
        	return true;
        }
    }
    Ti ringrazio veramente tanto per il supporto ch mi hai dato

    Ora non mi resta che smanettare per creare una piccola interfaccia grafica e poi ho finito

  8. #8
    Utente di HTML.it L'avatar di desa
    Registrato dal
    Oct 2008
    Messaggi
    569
    Figurati, nessun problema!

  9. #9
    L'ultimo algoritmo non mi soddisfava molto visto che era strutturato maluccio.

    Cosi mi sono messo a rifarlo.

    Allora questi è il main
    codice:
    static int[]v=new int[8];
    
        static int[][]m=new int[4][8];
    
        public static void main(String[]args){
    
            
    
            int c;
            
    
            for(int i=0;i<m.length;i++){
                
                for(int j=0;j<m[0].length;j++){
                    
                    do{
    
                        c=(int)(Math.random()*8)+1;
                        
                    }
                    
                    while(verificaNumeriDiversi(c)==false && verificaCoppie(c)==false);
    
                    v[j]=c;
    
                    m[i][j]=c;
    
                }
    
                for(int x=0;x<v.length;x++){
    
                    v[x]=0;
    
                }
    
            }
               
            for(int i=0;i<m.length;i++){
                
                for(int j=0;j<m[0].length;j++){
                    
                    System.out.print(m[i][j]+" ");
                    
                } 
                
                System.out.println();
    
            }
    Come vedete il controllo lo faccio ad ogni numero generato e non ad ogni matrice generata come prima.

    Ora il concetto è: continuo a generare un numero casuale fino a quando
    1>Il numero generato è diverso da ogni altro numero della riga
    2>La coppia di numeri è diversa e unica

    Ora per il punto 1 ho creato la seguente classe perfettamente funzionante

    codice:
    public static boolean verificaNumeriDiversi(int c){
    
            for(int x=0;x<v.length;x++){
    
                           if(c==v[x]){
    
                               return false;
    
                               }
    
           }
            
            return true;
    
        }
    L'array V è globale e viene usato per "contenere" i numeri estratti

    Per il punto 2 stavo pensando a qualcosa del genere
    codice:
        public static boolean verificaCoppie(int c){
    
             for(int i=0;i<m.length-1;i++){
    
                for(int j=0;j<m[0].length;j=j+2){
    
                    if(c==m[i+1][j] && m[i][j+1]==m[i+1][j+1]){
                        
                        return false;
                    }
                    
                }
             }
             return true;
    
        }
    ma non funziona non esegue il controllo

    Mi potete dare una mano? Come dicevo prima mi serve una classe che controlli gli accoppiamenti di ogni numero uscito

  10. #10
    L'ultimo algoritmo non mi soddisfava molto visto che era strutturato maluccio.

    Cosi mi sono messo a rifarlo.

    Allora questi è il main
    codice:
    static int[]v=new int[8];
    
        static int[][]m=new int[4][8];
    
        public static void main(String[]args){
    
            
    
            int c;
            
    
            for(int i=0;i<m.length;i++){
                
                for(int j=0;j<m[0].length;j++){
                    
                    do{
    
                        c=(int)(Math.random()*8)+1;
                        
                    }
                    
                    while(verificaNumeriDiversi(c)==false && verificaCoppie(c)==false);
    
                    v[j]=c;
    
                    m[i][j]=c;
    
                }
    
                for(int x=0;x<v.length;x++){
    
                    v[x]=0;
    
                }
    
            }
               
            for(int i=0;i<m.length;i++){
                
                for(int j=0;j<m[0].length;j++){
                    
                    System.out.print(m[i][j]+" ");
                    
                } 
                
                System.out.println();
    
            }
    Come vedete il controllo lo faccio ad ogni numero generato e non ad ogni matrice generata come prima.

    Ora il concetto è: continuo a generare un numero casuale fino a quando
    1>Il numero generato è diverso da ogni altro numero della riga
    2>La coppia di numeri è diversa e unica

    Ora per il punto 1 ho creato la seguente classe perfettamente funzionante

    codice:
    public static boolean verificaNumeriDiversi(int c){
    
            for(int x=0;x<v.length;x++){
    
                           if(c==v[x]){
    
                               return false;
    
                               }
    
           }
            
            return true;
    
        }
    L'array V è globale e viene usato per "contenere" i numeri estratti

    Per il punto 2 stavo pensando a qualcosa del genere
    codice:
        public static boolean verificaCoppie(int c){
    
             for(int i=0;i<m.length-1;i++){
    
                for(int j=0;j<m[0].length;j=j+2){
    
                    if(c==m[i+1][j] && m[i][j+1]==m[i+1][j+1]){
                        
                        return false;
                    }
                    
                }
             }
             return true;
    
        }
    ma non funziona non esegue il controllo

    Mi potete dare una mano? Come dicevo prima mi serve una classe che controlli gli accoppiamenti di ogni numero uscito

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.