[Java]

Messaggioda Magma » 10/07/2019, 11:42

Buon giorno :-D ,

ho svolto il seguente esercizio:

Si vuole risolvere il seguente problema. Data una sequenza di interi, verificare se esiste una tripla di interi consecutivi nella sequenza che contiene almeno un intero pari ed almeno un intero negativo.
Testo nascosto, fai click qui per vederlo
Ad esempio, la sequenza $[2,2,1,5,-7]$ è un’istanza negativa del problema, in quanto la tripla $[2,2,1]$ non contiene alcun intero negativo, la tripla $[2,1,5]$ non contiene alcun intero negativo e la tripla $[1,5,-7]$ non contiene alcun pari. La sequenza $[-1,2,5,1]$ è invece un’istanza positiva del problema, in quanto la tripla $[-1,2,5]$ contiene un intero pari $(2)$ ed un intero negativo $(-1)$. Anche la sequenza $[1,1,5,-2]$ è un’istanza positiva del problema, in quanto la tripla $[1,5,-2]$ contiene un intero pari $(-2)$ ed un intero negativo (ancora $-2$).


Io ho programma in questo modo

Testo nascosto, fai click qui per vederlo
Codice:
package EsoneroSecondo;
import java.util.Scanner;

public class UnoPariUnoNegativo {
   
   public static void main (String[] args) {
      
      System.out.println("QUanti interi vuole introdurre?");
      Scanner sc = new Scanner(System.in);
      int n = sc.nextInt();
      
      System.out.println("Introdurre "+n + " interi");
      int[] sequenza = new int[n];
      for(int i=0; i<sequenza.length; i++)
         sequenza[i] = sc.nextInt();
      
      System.out.println("Esistono tre interi consecutivi nella sequenza "
                     + "di cui almeno uno è pari e almeno uno negativo? "
                     + unoPariUnoNegativo(sequenza));
      sc.close();
         
   }

   public static boolean unoPariUnoNegativo(int[] interi) {
      
      boolean esistono = false;
      
      
      for(int i=0; i<=interi.length-3; i++)
         if(  (interi[i] %2 == 0 || interi[i+1] %2 == 0  || interi[i+2] %2 == 0 ) &&
             (interi[i] <0      || interi[i+1] <0       || interi[i+2] <0     )   )
               esistono = true;
         
      return esistono;
   }
}


mentre la soluzione proposta è la seguente:

Testo nascosto, fai click qui per vederlo
Codice:
package SecondoEsonero;
import java.util.Scanner;

/* programma che legge una sequenza di interi e stampa un messaggio che
 * indica se esiste una tripla di interi che ne contiene almeno uno pari ed uno negativo */
public class UnoPariUnoNegativo {

   /* metodo che verifica se esistono tre elementi consecutivi in un
    * array di interi di cui almeno uno è pari ed uno negativo */
   public static boolean unoPariUnoNegativo(int[] seq) {
      boolean pariNeg;         // variabile di esistenza
      int i;                  // variabile contatore
      pariNeg = false;         // tripla ancora non trovata
      
      /* guarda tutte le triple */
      i=0;
      while(i<= seq.length-3 && !pariNeg)
         /* tripla corrente soddisfa la proprietà? */
         if((seq[i] % 2 == 0 || seq[i+1] % 2 == 0 || seq[i+2] % 2 == 0) &&
            (seq[i] < 0 || seq[i+1] < 0 || seq[i+2] < 0))
            pariNeg = true;
         else
            i++;
      
      return pariNeg;
   }
   
   /* metodo principale */
   public static void main(String[] args) {
      int lunghezza;         // lunghezza della sequenza
      
      /* input */
      System.out.println("Quanti interi vuoi introdurre?");
      Scanner sc = new Scanner(System.in);
      lunghezza = sc.nextInt();
      int[] sequenza = new int[lunghezza];
      for(int i=0; i<lunghezza; i++) {
         System.out.print("Introduci un intero: ");
         sequenza[i] = sc.nextInt();
      }
      
      /* output */
      if(unoPariUnoNegativo(sequenza))
         System.out.println("Vero! Esistono tre elementi consecutivi che ne contengono almeno uno pari ed uno negativo");
      else
         System.out.println("Falso! Non esistono tre elementi consecutivi che ne contengono almeno uno pari ed uno negativo");
      sc.close();
   }
}


La differenza sta nel metodo ausiliario in cui io ho usato for
Codice:
boolean esistono = false;
      
      
      for(int i=0; i<=interi.length-3; i++)
         if(  (interi[i] %2 == 0 || interi[i+1] %2 == 0  || interi[i+2] %2 == 0 ) &&
             (interi[i] <0      || interi[i+1] <0       || interi[i+2] <0     )   )
               esistono = true;
         
      return esistono;


al posto di while
Codice:
/* guarda tutte le triple */
      i=0;
      while(i<= seq.length-3 && !pariNeg)
         /* tripla corrente soddisfa la proprietà? */
         if((seq[i] % 2 == 0 || seq[i+1] % 2 == 0 || seq[i+2] % 2 == 0) &&
            (seq[i] < 0 || seq[i+1] < 0 || seq[i+2] < 0))
            pariNeg = true;
         else
            i++;
      return pariNeg;


I due metodi si equivalgono oppure è preveribile usare while e perchè? Inoltre nella condizione di "while" non capisco perché sia necessario mettere !pariNeg (dove pariNeg è stato inizializzato con valore falso).
Magma
Senior Member
Senior Member
 
Messaggio: 1403 di 1421
Iscritto il: 03/09/2015, 13:15

Re: [Java]

Messaggioda claudio86 » 10/07/2019, 13:04

Nella soluzione con il while, il ciclo termina non appena viene trovata una tripla che soddisfa i requisiti. Nella soluzione con il for, invece, il ciclo visita sempre tutta la lista.
Dal punto di vista semantico sono equivalenti, però la soluzione con il while potrebbe essere più veloce. Nella stragrande maggioranza dei casi la differenza è troppo piccola per essere misurabile. Inoltre si tratta di una micro-ottimizzazione che non cambia la complessità della funzione, che rimane lineare.

In generale, i cicli for e while sono equivalenti. Però, dal punto di vista idiomatico, il ciclo for viene usato quando si conosce a priori il numero di iterazioni (ad esempio quando si scorre un'intera sequenza), mentre il ciclo while viene usato quando la condizione di uscita può cambiare durante un'iterazione.
Ad esempio, puoi aggiungere la stessa condizione usata nella soluzione proposta nel tuo ciclo for:
Codice:
for(int i=0; i<=interi.length-3 && !esistono; i++)
"This theorem, as many others, is proven by writing zero in a creative way…"
claudio86
Average Member
Average Member
 
Messaggio: 519 di 537
Iscritto il: 09/01/2011, 15:12

Re: [Java]

Messaggioda Magma » 10/07/2019, 13:14

Ti ringrazio per la risposta! :smt023 In pratica appena è stata trovata la tripla richiesta, il ciclo termina per la presenza del valore " … && false " :-D
Magma
Senior Member
Senior Member
 
Messaggio: 1404 di 1421
Iscritto il: 03/09/2015, 13:15


Torna a Informatica

Chi c’è in linea

Visitano il forum: Nessuno e 12 ospiti