Forum Informatica Unict

LAUREA TRIENNALE (D.M. 270/04) => Programmazione 1, 9 CFU => Topic started by: Luxandro on 11-12-2010, 12:35:52



Title: Metodo Prima Prova
Post by: Luxandro on 11-12-2010, 12:35:52
Salve!  .ciaociao

Vi propongo di seguito la possibile risoluzione di uno dei tanti metodi assegnati dal prof. nelle prime prove degli anni precedenti.
Non essendo un programmatore esperto, possibili correzioni o suggerimenti sono ben accetti!!  :yoh

PS: So che la consizione dell'if è illeggibile, ma è l'unico modo per risparmiare memoria sull'utilizzo delle variabili  .rido
Quote
/* Scrivere un metodo che prenda in input due matrici A e B di byte delle stesse dimensioni, e restituisca un boolean che indichi se esiste un tappeto in A il cui valore differisce al più di una unità da quello di un tappeto in B (in qualunque posizione). Un tappeto è l’insieme di quattro elementi contigui disposti a quadrato; il suo valore è dato dal prodotto dei quattro numeri.*/

public boolean Tappeto(byte[][] A, byte[][] B)
{   
   int i,j,k,z;
   boolean trovato=false;
   
   for(i=0;i<A.length-2;i++)
   {
      for(j=0;j<A[ i ].length-2;j++)
      {
         for(k=0;k<A.length-2;k++)
         {
            for(z=0;z<A[k].length-2;z++)
            {
               if((A[ i ][j]*A[ i ][j+1]*A[i+1][j]*A[i+1][j+1]==B[k][z]*B[k][z+1]*B[k+1][z]*B[k+1][z+1])||
((A[ i ][j]*A[ i ][j+1]*A[i+1][j]*A[i+1][j+1]-B[k][z]*B[k][z+1]*B[k+1][z]*B[k+1][z+1])==1)||
((B[k][z]*B[k][z+1]*B[k+1][z]*B[k+1][z+1]-A[ i ][j]*A[ i ][j+1]*A[i+1][j]*A[i+1][j+1])==1))
               {   
                  trovato=true;
                  return trovato;
               }
            }
         }
      }
   }
return trovato;
}


Title: Re:Metodo Prima Prova
Post by: Daréios89 on 11-12-2010, 13:09:24
Non ho assolutamente letto il metodo e il suo funzionamento e non credo lo farò.
Hai già precisato che quello che hai fatto è per evitare uno spreco di memoria, ma secondo me non è una scelta saggia.
Intanto perchè lo scopo di programmazione 1 è un altro, i problemi sull' efficienza verranno dopo.
Numero due, perchè credo che a volte, è meglio preferire la leggibilità all' efficienza, se parliamo di casi in cui un' istruzione non influisce notevolmente sulla complessità.
Visto che i codici di programmazione 1 non sono abominevoli, non credo ci sia un risparmio così elevato, e in ogni caso il prof credo avrebbe tagliato una cosa del genere.


Title: Re:Metodo Prima Prova
Post by: Luxandro on 11-12-2010, 13:14:00
Ok! L'ho modificato! Grazie per il consiglio!  .rido

Ci sono errori?

Quote
/* Scrivere un metodo che prenda in input due matrici A e B di byte delle stesse dimensioni, e restituisca un boolean che indichi se esiste un tappeto in A il cui valore differisce al più di una unità da quello di un tappeto in B (in qualunque posizione). Un tappeto è l’insieme di quattro elementi contigui disposti a quadrato; il suo valore è dato dal prodotto dei quattro numeri.*/

public boolean Tappeto(byte[][] A, byte[][] B)
{   
   int i,j,k,z,prodottoA=0,prodottoB=0;
   boolean trovato=false;
   
   for(i=0;i<A.length-2;i++)
   {
      for(j=0;j<A[ i ].length-2;j++)
      {
         for(k=0;k<A.length-2;k++)
         {
            for(z=0;z<A[k].length-2;z++)
            {
               prodottoA=A[ i ][j]*A[ i ][j+1]*A[i+1][j]*A[i+1][j+1];
               prodottoB=B[k][z]*B[k][z+1]*B[k+1][z]*B[k+1][z+1];
               if((prodottoA==prodottoB)||(prodottoA-prodottoB==1)||(prodottoB-prodottoA==1))
               {   
                  trovato=true;
                  return trovato;
               }
            }
            prodottoA=0;
            prodottoB=0;
         }
      }
   }
return trovato;
}


Title: Re:Metodo Prima Prova
Post by: Daréios89 on 11-12-2010, 14:56:01
Come pensavo, penso non di non sbagliarmi, alla fine ci sono solo assegnamenti e un if che sono eseguiti in tempo costante quindi non c'è alcun risparmio, così si capisce mooooooolto meglio.
A parte questo ho fatto pochi controlli ma mi sembra che vada bene il programma, al massimo fai qualche altra prova tu su qualche altro input:

Code:
public class TappetoEx
{
public static void main(String [] args)
{
byte[][]A={{1,4,3,5},
                 {4,3,5,6}};
byte B[][]={{1,3,1,4},
    {5,6,4,3}};

    System.out.println(Tappeto(A,B));
}




public static boolean Tappeto(byte[][] A, byte[][] B)
{   
   int i,j,k,z,prodottoA=0,prodottoB=0;
   boolean trovato=false;
   
   for(i=0;i<A.length-1;i++)
   {
      for(j=0;j<A[ i ].length-1;j++)
      {
         for(k=0;k<B.length-1;k++)
         {
            for(z=0;z<B[k].length-1;z++)
            {
               prodottoA=A[ i ][j]*A[ i ][j+1]*A[i+1][j]*A[i+1][j+1];
               prodottoB=B[k][z]*B[k][z+1]*B[k+1][z]*B[k+1][z+1];
               if((prodottoA==prodottoB)||(prodottoA-prodottoB==1)||(prodottoB-prodottoA==1))
               {   
                  trovato=true;
                  return trovato;
               }
            }
            prodottoA=0;
            prodottoB=0;
         }
      }
   }
   return trovato;      //devi mettere sempre alla fine di un metodo una return, la precedente sta nell' if ma ogni metodo che ritorna qualcosa vuole una return specificata.
}
}


Title: Re:Metodo Prima Prova
Post by: Luxandro on 11-12-2010, 14:59:35
Grazie mille per l'aiuto Dareios! Sei stato utilissimo!  .rido


Title: Re:Metodo Prima Prova
Post by: ɹǝǝuıƃuǝsɹǝʌǝɹ on 11-12-2010, 15:11:51
La variabile trovato è assolutamente inutile in quel codice. .sisi
Le due return che ne restituiscono il valore possono essere sostituite dalle return della rispettiva costante (true o false).

Come ti faceva notare Daréios, i cicli dovevano finire usando come condizione il confronto con length-1 (non length - 2), come infatti avevi scritto nella prima versione (poi modificata) del codice inserito in questi messaggi :boh.

Suggerimenti:
  • È buona pratica evitare di infilare return molto dentro al codice (nel tuo caso è dentro a ben 4 cicli for); per evitare ciò avrei modificato tutte le condizioni di uscita dei cicli for mettendole in AND (&&) con !trovato, avrei tolto la return annidata e avrei lasciato la sola return trovato; alla fine del codice: in questo caso la variabile trovato diventa magicamente utilissima;
  • Avrei accorpato la condizione che verifica il successo della ricerca tramite Math.abs (...) (http://tinyurl.com/3yxvk9b), ad esempio con:
Code:
if (Math.abs (prodottoA - prodottoB) <= 1)
  • Aggiungo (edit) che è bene non fidarsi mai delle certezze che il committente spera di poter garantire di offrirci: in questo caso è detto che le matrici A e B hanno le stesse dimensioni: in generale, avrei ignorato questa "facilitazione" e avrei fatto in modo che le variabili k e z fossero limitate dai rispettivi valori length che provengono da B
     .ciaociao


Title: Re:Metodo Prima Prova
Post by: Luxandro on 11-12-2010, 15:16:41
Hai ragione...converrebbe utilizzare il boolean nelle condizioni dei for per dargli un senso  :-)|

Una curiosità: il metodo---> Math.abs (prodottoA - prodottoB) <= 1 cosa ritorna esattamente?


Title: Re:Metodo Prima Prova
Post by: ɹǝǝuıƃuǝsɹǝʌǝɹ on 11-12-2010, 15:19:20
Una curiosità: il metodo---> Math.abs (prodottoA - prodottoB) <= 1 cosa ritorna esattamente?
Valore assoluto .arrossisco.
Ho evidenziato appositamente la prima menzione di tale metodo in blu/grassetto/sottolineato affinché si capisca che è un link cliccabile: cliccalo e segui il link :-OK.


Title: Re:Metodo Prima Prova
Post by: Luxandro on 11-12-2010, 15:22:45
Ah ok non avevo visto scusa!  :pray

Grazie per i consigli!!


Title: Re:Metodo Prima Prova
Post by: Luxandro on 11-12-2010, 17:06:25
Vorrei chiedervi un piccolo chiarimento  .rido

Quando si ha a che fare con array e stringhe di solito si usa length che ritorna la dimensione dell'array o della stringa in questione.
Il mio dubbio è il seguente:

Nome.length() è il metodo, mentre Nome.length è l'attributo della classe in questione ed essendo di tipo public puo essere richiamato all'esterno di essa.
Che differenza c'è tra i due?? Ovvero, ritornano la stessa cosa e quindi si puo' usare sia uno che l'altro o ritornano due cose differenti?

Ho intuito che per gestire tipi di dati primitivi quali byte, int, ecc. , si utilizza l'attributo; mentre per tipi di dati non primitivi il metodo nome.length(), ma probabilmente mi sto sbagliando  :pray

Inoltre ho cercato di risolvere il seguente esercizio ma mi trovo in difficoltà quando si deve indicare la seconda dimensione della matrice di copia S1. E' giusto farlo con un for?

Quote
/* Scrivere un metodo che prenda da input una matrice S di stringhe, e restituisca una copia S' di S in cui ogni stringa di lunghezza x:
- Resta identica, se x=8;
- Subisce l'inserimento a sinistra di (8-x) caratteri "=", se x<8;
- Subisce l'eleminazione dei primi (x-8) caratteri, se x>8;*/

public String Stringa(String[][] S)
{
       String[][] S1;

   for(i=0;i<S.length;i++)
   {
      S1=new String[S.length][S[ i ].length];
   }

   int x,y,i,j,z;

   for(i=0;i<S.length;i++)
   {
      for(j=0;j<S[ i ].length;j++)
      {
         if(S[ i ][j].length()==8)
            S1[ i ][j]=S[ i ][j];
         if(S[ i ][j].length()< 8 )
         {
            for(z=0;(z<(8-x));z++)
               S1[ i ][j]+="=";
         S1[ i ][j]+=S[ i ][j].substring((8-x)+1,S[ i ][j].length());
         }

         if(S[ i ][j].length()> 8 )
         {
            for(z=0;(z<(x-8));z++)
               S1[ i ][j]+=" ";
         S1[ i ][j]+=S[ i ][j].substring(0,(x-8)+1);
         }
      }
   }
return S1;
}



Title: Re:Metodo Prima Prova
Post by: Stardust on 11-12-2010, 19:13:21
Vorrei chiedervi un piccolo chiarimento  .rido

Quando si ha a che fare con array e stringhe di solito si usa length che ritorna la dimensione dell'array o della stringa in questione.
Il mio dubbio è il seguente:

Nome.length() è il metodo, mentre Nome.length è l'attributo della classe in questione ed essendo di tipo public puo essere richiamato all'esterno di essa.
Che differenza c'è tra i due?? Ovvero, ritornano la stessa cosa e quindi si puo' usare sia uno che l'altro o ritornano due cose differenti?

Ho intuito che per gestire tipi di dati primitivi quali byte, int, ecc. , si utilizza l'attributo; mentre per tipi di dati non primitivi il metodo nome.length(), ma probabilmente mi sto sbagliando  :pray

Inoltre ho cercato di risolvere il seguente esercizio ma mi trovo in difficoltà quando si deve indicare la seconda dimensione della matrice di copia S1. E' giusto farlo con un for?

Quote
/* Scrivere un metodo che prenda da input una matrice S di stringhe, e restituisca una copia S' di S in cui ogni stringa di lunghezza x:
- Resta identica, se x=8;
- Subisce l'inserimento a sinistra di (8-x) caratteri "=", se x<8;
- Subisce l'eleminazione dei primi (x-8) caratteri, se x>8;*/

public String Stringa(String[][] S)
{
       String[][] S1;

   for(i=0;i<S.length;i++)
   {
      S1=new String[S.length][S[ i ].length];
   }

}
...................................................................

Mi sa che hai scritto troppo codice per qst esercizio  :yoh ..... cmq per il length() e length il primo è un metodo per sapere la lunghe ecc ecc metre l' altro nn è un metodo  e poi dipende se usi il tipo Stringa oppure gli int ma qst cose sn semplici definizioni che si trovano dappertutto  .smile


Title: Re:Metodo Prima Prova
Post by: Luxandro on 11-12-2010, 19:23:39
Quote
Mi sa che hai scritto troppo codice per qst esercizio   :yoh..... cmq per il length() e length il primo è un metodo per sapere la lunghe ecc ecc metre l' altro nn è un metodo  e poi dipende se usi il tipo Stringa oppure gli int ma qst cose sn semplici definizioni che si trovano dappertutto .smile

Quindi in pratica quello che ho detto io  :[Emoticon] Asd: dipende se si sta lavorando con tipi di dati primitivi o meno  .rido

Per quanto riguarda l'esercizio in che senso ho scritto troppo codice?? tu cosa avresti omesso??



Title: Re:Metodo Prima Prova
Post by: Daréios89 on 11-12-2010, 20:33:43
Quanto alla differenza tra length e length() come dicevi dipende se si ha a che fare con dati primitivi o meno.
Per farla breve, quando hai a che fare con un array e devi verificare la lunghezza userai length, quando avrai a che fare con le stringhe dovrai ricordarti di mettere le parentesi dopo, quindi  length().
Il perchè lo vedrete più avanti, o forse lo sapete già, dipende dal fatto che le stringhe non siano dati primitivi ma oggetti, e quindi come per tutti gli oggetti i relativi metodi vogliono sempre le parentesi tonde perchè potrebbero esserci degli argomenti come parametri.

Quanto al codice:

Quote
    String[][] S1;

   for(i=0;i<S.length;i++)
   {
      S1=new String[S.length][S[ i ].length];
   }

 .penso

Così facendo...non credo abbia senso...tu ad ogni iterazione del for costruisci un nuovo array, basta farlo una volta:

Code:
String[][] S1=new String[S.length][S[0].length];

Penso che la tua matrice non sia frastagliata perciò dovrebbe andare bene così.
Quanto al resto non ho controllato, non ho molto tempo adesso.


Title: Re:Metodo Prima Prova
Post by: ɹǝǝuıƃuǝsɹǝʌǝɹ on 12-12-2010, 03:03:09
Premesso che non c'è modo migliore automatizzato di capire gli errori se non compilare il proprio codice e fare qualche test (nel caso la compilazione vada a buon fine) con casi estremi di input...

...elencherò gli errori e le cose anomale (da cosiddetta cattiva programmazione .arrossisco) man mano che scorro il codice, che in questo forum va inserito nell'apposito tag [CODE] |-O (non [QUOTE], che poi per evitare errori nel parsing di [i] bisogna circondare la i di spazi :boh...).
Code:
public String Stringa(String[][] S)
Come noterai leggendo l'ultima istruzione, la return (che è corretta), il tuo metodo deve restituire String [][] .sisi, non String .nono.
Anche il compilatore ti avrebbe fatto notare questo errore (seppur segnalandolo sulla return piuttosto che qui :boh).
Code:
{
       String[][] S1;
Qui sopra la dichiarazione di S1 è più indentata del resto del codice allo stesso livello: bisogna curare anche questo aspetto per la leggibilità .sisi.

Code:
  for(i=0;i<S.length;i++)
La variabile i non esiste (ancora); anche il compilatore ti avrebbe avvisato di questo errore.
Code:
  {
      S1=new String[S.length][S[ i ].length];
   }
In questo blocco puoi tranquillamente fare a meno delle parentesi graffe, giacchè il body del for contiene una sola istruzione (è bene evitare le parentesi in tali casi perché, quando troppo vicine, diminuiscono la leggibilità .sisi);

in secondo luogo ci sono ben due errori: ad ogni iterazione, S1 viene riassegnato totalmente (righe e colonne .huh) facendo perdere il vecchio contenuto che il garbage collector a suo tempo forse si degnerà di ripulire dalla memoria :boh (primo errore) e in più il riassegnamento avviene con un nuovo array bidimensionale rettangolare, mentre non puoi supporre che l'array bidimensionale sia rettangolare (matrice a due dimensioni, cioè) .nono.
In questi casi, ogni riga va assegnata indipendentemente dalle altre con un array della giusta dimensione .leggo.
Code:
  int x,y,i,j,z;
È bene dichiarare le variabili solo nel contesto più piccolo entro cui ha senso che esistano (per evitare l'uso in- volontario di eventuali valori residui di codice precedente e per dare un unico senso logico alla loro esistenza .wink).
Code:
  for(i=0;i<S.length;i++)
   {
      for(j=0;j<S[ i ].length;j++)
      {
Dentro questo ciclo for più interno si fa un uso spregiudicato di più costrutti if in sequenza, aumentando inutilmente il numero di confronti da fare; nei casi in cui le condizioni sono mutualmente esclusive (come questo), è bene fare una serie di if a cascata uno dentro il ramo else del precedente, o, se vuoi chiamarli così, una serie di if... else if... else if... :boh;
inoltre, anche volendo usare gli if a cascata, bisogna evitare di chiamare troppe volte metodi già richiamati e il cui valore restituito non è cambiato, quindi in questo caso sarebbe bene assegnare a qualche variabile il valore
di S [i][j].length ().
Code:
        if(S[ i ][j].length()==8)
            S1[ i ][j]=S[ i ][j];
         if(S[ i ][j].length()< 8 )
         {
            for(z=0;(z<(8-x));z++)
Mancata inizializzazione di x (che anche il compilatore ti avrebbe segnalato .arrossisco), e che si suppone logicamente debba contenere il valore di S[i][j].length () (risolvendo questo errore risolvi anche quello della chiamata multipla menzionato or ora :-OK);

inoltre, tutte le parentesi dentro la condizione di uscita del for sono completamente inutili (e quelle più esterne peggiorano pure la leggibilità .sisi).
Code:
              S1[ i ][j]+="=";
Errore grave: giacchè non hai inizializzato alcuna stringa della matrice S1 .nono, tutte le sue celle conterranno null e l'assegnazione con lettura (+=) produrrà inevitabilmente una java.lang.NullPointerException (http://download.oracle.com/javase/6/docs/api/java/lang/NullPointerException.html) .sisi.
Code:
        S1[ i ][j]+=S[ i ][j].substring((8-x)+1,S[ i ][j].length());
Errore grave di logica: a questo punto bisogna banalmente concatenare tutta S [i][j] a destra di S1 [i][j]; considera che per valori x ∈ {0, 1, 2, 3, 4}, questo codice lancia una java.lang.StringIndexOutOfBoundsException (http://download.oracle.com/javase/6/docs/api/java/lang/StringIndexOutOfBoundsException.html), cosa di cui nemmeno la documentazione ufficiale di String.substring (int, int) (http://tinyurl.com/32g68x8) ci informa!!! :-)| .bah.
Code:
        }

         if(S[ i ][j].length()> 8 )
         {
            for(z=0;(z<(x-8));z++)
               S1[ i ][j]+=" ";
         S1[ i ][j]+=S[ i ][j].substring(0,(x-8)+1);
Errore di malintendimento: in questo caso bisogna semplicemente assegnare a S1[i][j] la sottostringa formata dai primi 8 caratteri di S[i][j] :boh, invece la si è dapprima riempita di spazi (con il lancio inevitabile di una java.lang.NullPointerException (http://download.oracle.com/javase/6/docs/api/java/lang/NullPointerException.html) analogamente al caso precedente .arrossisco) e poi unita con i primi x-7 simboli (stranamente 1 in più rispetto agli x-8 che avanzavano rispetto appunto a 8=lunghezza prevista :pray) della stringa originale :-)|.
Il resto del codice (chiusura blocchi e return finale) è OK  :-OK.


Facendo un po' di pulizia e seguendo i miei consigli il codice sarebbe venuto una cosa del genere:
Code:
   public String [][] mioMetodo (String [][] S)
    {
        String [][] S1 = new String [S.length][];
        
        for (int i = 0; i < S.length; i++)
            S1 [i] = new String [S [i].length];
        
        for (int i = 0; i < S.length; i++)
            for (int j = 0; j < S [i].length; j++)
            {
                int x = S [i][j].length ();
                if (x == 8)
                    S1 [i][j] = S [i][j];
                else if (x > 8)
                    S1 [i][j] = S [i][j].substring (0, 8);
                else
                {
                    S1 [i][j] = "";
                    for (int z = 0; z < 8-x; z++)
                        S1[i][j] += "=";
    
                    S1 [i][j] += S [i][j];
                }
            }

        return S1;
    }
che è leggibile ma, secondo me, poco elegante (leggibilità ed eleganza non vanno di pari passo, come utilità e arte insomma :boh).

Un giorno si spera arriverete a scrivere codice elegante come questo:
Code:
    public static String [][] mioMetodoElegante (String [][] S)
    {
        String [][] S1 = new String [S.length][];
       
        for (int i = 0; i < S.length; i++)
        {
            S1 [i] = new String [S [i].length];
            for (int j = 0; j < S [i].length; j++)
            {
                int x = S [i][j].length (); S1 [i][j] = "";
                for (int z = 0, max = Math.max (0, 8 - x); z < max; z++) S1 [i][j] += "=";
                S1 [i][j] += S [i][j].substring (0, Math.min (x, 8));
            }
        }
        return S1;
    }
Se ora non lo capite, non ve lo spiego: l'arte va interpretata |-O!


Title: Re:Metodo Prima Prova
Post by: Luxandro on 12-12-2010, 09:40:38
Ti ringrazio per le correzioni e i consigli! .rido

Quindi per quel che riguarda l'assegnazione della seconda dimensione della matrice basta inserire la new all'interno del primo ciclo for, cosicchè, ad ogni iterazione del primo ciclo, venga assegnata la dimensione alla matrice (correggimi se sbaglio  :-)|)

Code:
 for (int i = 0; i < S.length; i++)
        {
            S1 [i] = new String [S [i].length];
            for (int j = 0; j < S [i].length; j++)
            {

Ho solo un ultimo dubbio quando si verifica la condizione x>8

Code:
  else if (x > 8)
                    S1 [i][j] = S [i][j].substring (0, 8);

L'esercizio in questo caso chiedeva che avvenisse l'eliminazione dei primi (x-8) caratteri, se x>8.

perchè assegni alla stringa della matrice S1 la sottostringa che va da 0 a 7 di S?

Non sarebbe più corretto scrivere

Code:
 else if (x > 8)
                    S1 [i][j] = S [i][j].substring (x-8,x);

cosicchè vengano "ignorati" i primi x-8 caratteri della stringa S[ i ][j]?



Title: Re:Metodo Prima Prova
Post by: ɹǝǝuıƃuǝsɹǝʌǝɹ on 12-12-2010, 12:40:51
Raggione hai :-)|!

Si vede che ero addummisciuto :boh.

A questo punto si può benissimo usare la versione con un solo parametro di substring
Code:
S1 [i][j] = S [i][j].substring (x - 8);

Per quanto riguarda l'inserimento dentro il primo ciclo for della new, beh si a prima vista l'avevo fatto anche io in un for che faceva solo quello.
Code:
for (int i = 0; i < S.length; i++)
    S1 [i] = new String [S [i].length];
prima del resto del codice, per poi accorgermi che potevo farlo in un'unica soluzione senza problemi |-O.


Di conseguenza, anche mioMetodoElegante va cambiato, addirittura semplificato :pray
Code:
    public static String [][] mioMetodoElegante (String [][] S)
    {
        String [][] S1 = new String [S.length][];
       
        for (int i = 0; i < S.length; i++)
        {
            S1 [i] = new String [S [i].length];
            for (int j = 0; j < S [i].length; j++)
            {
                int x = S [i][j].length (); S1 [i][j] = "";
                for (int z = 0, max = Math.max (0, 8 - x); z < max; z++) S1 [i][j] += "=";
                S1 [i][j] += S [i][j].substring (Math.max (0, x - 8));
            }
        }
        return S1;
    }
In pratica è cambiata solo l'ultima concatenazione con lettura su S1 [i][j] :boh.


Title: Re:Metodo Prima Prova
Post by: Luxandro on 12-12-2010, 13:34:02
Grazie mille!!!  :-OK

Adesso ho le idee più chiare!  .smile

Un'ultima cosa....tu hai fatto notare, precedentemente, che avresti utilizzato in modo differente il boolean
Quote
La variabile trovato è assolutamente inutile in quel codice.
Le due return che ne restituiscono il valore possono essere sostituite dalle return della rispettiva costante (true o false).

In che senso?
Code:
trovato=true;
return trovato;
Ho scritto cosi poichè l'esercizio dice
Quote
...restituisca un boolean che indichi se esiste un tappeto in A il cui valore differisce al più di una unità da quello di un tappeto in B
quindi "credo" che al primo tappeto possa uscire e quindi il return all'interno di tutti i cicli avrebbe un senso  :boh


Riporto di seguito un esercizio più semplice, ma in cui ho utilizzato il boolean e il return alla stessa maniera
Code:
/* Scrivere un metodo che prenda in input una matrice A di long ed un array S di byte, e restituisca un boolean
che indichi se esistono due valori x e y in S tali che la somma degli elementi nella riga di indice x di A sia pari
a quella della riga di indice y di A (Non si possono usare array ausiliari)*/

public boolean Metodo(long[][] A, byte[] S)
{
boolean trovato;
for(int k=0;k<S.length-1,k++)
{
long sommaX=0,sommaY=0; trovato=false;
x=S[k];y=S[k+1];
if((x<A.length)&&(y<A.length))
{
for(int j=0;j<A[i].length;j++)
{
sommaX+=A[x][j];
sommaY+=A[y][j];
}
}
if(sommaX==sommaY)
{
trovato=true;
return trovato;
}
}
return trovato;
}



Title: Re:Metodo Prima Prova
Post by: ɹǝǝuıƃuǝsɹǝʌǝɹ on 12-12-2010, 14:26:03
Il codice di quest'ultimo esercizio non compila perché hai usato delle variabili mai dichiarate, cioè "simboli non definiti" direbbe il compilatore (variabili x e y) oppure hai usato una variabile (trovato) non inizializzata (nel caso in cui S.length fosse <= 1 faresti return trovato, senza mai essere entrato nel ciclo for e quindi senza mai averla inizializzata).

Ti lascio una versione corretta del codice prima con la variabile booleana trovato (inutile) e poi senza, così vedi la differenza :-OK:
Code:
   public boolean Metodo (long [][] A, byte [] S)
    {
     boolean trovato = false;
     for (int a = 0; a < S.length - 1; a++)
        for (int b = a + 1; b < S.length; b++)
        {
            int x = S [a], y = S [b];

            if (x < A.length && y < A.length)
            {
                long sommaX = 0, sommaY = 0;

                //posso usare la sola A [x].length anche per limitarmi in A[y], poiché A si suppone matrice (quindi arraby bidimensionale rettangolare)
                for (int c = 0; c < A [x].length; c++)
                {
                    sommaX += A [x][c];
                    sommaY += A [y][c];
                }
                
                if (sommaX == sommaY)
                {
                    trovato = true;
                    return trovato;
                }
            }
        }
    
     return trovato;
    }
    
    public boolean Metodo2 (long [][] A, byte [] S)
    {
     for (int a = 0; a < S.length - 1; a++)
        for (int b = a + 1; b < S.length; b++)
        {
            int x = S [a], y = S [b];

            if (x < A.length && y < A.length)
            {
                long sommaX = 0, sommaY = 0;
                
                    //posso usare la sola A [x].length anche per limitarmi in A[y], poiché A si suppone matrice (quindi arraby bidimensionale rettangolare)
                for (int c = 0; c < A [x].length; c++)
                {
                    sommaX += A [x][c];
                    sommaY += A [y][c];
                }
                
                if (sommaX == sommaY)
                    return true;
            }
        }
    
     return false;
    }


Title: Re:Metodo Prima Prova
Post by: Luxandro on 12-12-2010, 14:38:08
Si lo so! errori di distrazione  :"-(  a volte assegno senza dichiarare  :boh

Code:
public boolean Metodo(long[][] A, byte[] S)
{
for(int k=0;k<S.length-1,k++)
{
long sommaX=0,sommaY=0; trovato=false;
int x=S[k],y=S[k+1];
if((x<A.length)&&(y<A.length))
{
for(int j=0;j<A[i].length;j++)
{
sommaX+=A[x][j];
sommaY+=A[y][j];
}
if(sommaX==sommaY)
return true;
}
return false;
}


Title: Re:Metodo Prima Prova
Post by: Luxandro on 12-12-2010, 16:36:28
Code:
public boolean Metodo2 (long [][] A, byte [] S)
    {
     for (int a = 0; a < S.length - 1; a++)
        for (int b = a + 1; b < S.length; b++)
        {
            int x = S [a], y = S [b];

            if (x < A.length && y < A.length)
            {
                long sommaX = 0, sommaY = 0;
                
                    //posso usare la sola A [x].length anche per limitarmi in A[y], poiché A si suppone matrice (quindi arraby bidimensionale rettangolare)
                for (int c = 0; c < A [x].length; c++)
                {
                    sommaX += A [x][c];
                    sommaY += A [y][c];
                }
                
                if (sommaX == sommaY)
                    return true;
            }
        }
    
     return false;
    }
Ma perchè usi 3 cicli for??
Ne basterebbero 2, uno che "cicla" l'array e l'altro che "cicla" le righe della matrice...


Title: Re:Metodo Prima Prova
Post by: ɹǝǝuıƃuǝsɹǝʌǝɹ on 12-12-2010, 17:13:07
Ma perchè usi 3 cicli for??
Ne basterebbero 2, uno che "cicla" l'array e l'altro che "cicla" le righe della matrice...
.nono.

Se guardi bene cosa dice la consegna dell'esercizio:
Quote
Scrivere un metodo che prenda in input una matrice A di long ed un array S di byte, e restituisca un boolean
che indichi se esistono due valori x e y in S tali che la somma degli elementi nella riga di indice x di A sia pari
a quella della riga di indice y di A (Non si possono usare array ausiliari)
ti accorgerai che non è stato mai specificato che x e y fossero due valori consecutivi in S, mentre il tuo codice arbitrariamente lo suppone e li sceglie secondo tale restrizione .sisi.

Quindi, se devo scegliere due elementi da un array, devo fare due cicli (in realtà se ne può fare uno moooooolto lungo e fare calcoli in mezzo, ma questa è programmazione criptica avanzata |-O .coolio).


Title: Re:Metodo Prima Prova
Post by: Luxandro on 12-12-2010, 17:14:58
Hai ragione!  :[Emoticon] Asd:

Lo stesso errore dell'altro esercizio  :-)|