Massimo e secondo elemento di un vettore

Lo scopo di questo esercizio è di trovare il massimo elemento in un vettore. In più, si vuole anche l'elemento che lo segue, ossia quello che è secondo in ordine di grandezza dopo il massimo. Sia x questo vettore, per esempio:

int x[]={5, 38, 71, 4, 37, 70, 3, 36, 69, 2, 35, 68, 1, 34, 67, 0, 33, 66, 99, 32, 65};

Trovare l'elemento massimo è stato già fatto. Il problema è solo quello di trovare l'elemento che lo segue. È chiaro che dobbiamo analizzare uno per volta tutti gli elementi del vettore, ed è quindi necessario usare un ciclo. Per trovare effettivamente il massimo e il secondo elemento, usiamo la tecnica solita:

  1. facciamo una prima ipotesi su quali sono il massimo e il secondo;
  2. a ogni passo del ciclo, verifichiamo se la ipotesi è effettivamente valida, altrimenti correggiamo i valori di ipotesi;
  3. alla fine del ciclo i valori di massimo e secondo risultano per forza corretti

Il primo passo è quello di considerare solo i primi due elementi del vettore, e di trovare il massimo e il secondo su di essi. Chiaramente, quello maggiore dei due è il massimo, mentre l'altro è il secondo. Memorizziamo quindi nelle variabili max e sec il massimo corrente e il secondo corrente. Questo primo passo viene eseguito dal seguente codice:

    if ( x[0]>x[1] ) {
      max=x[0];
      sec=x[1];
    }
    else {
      max=x[1];
      sec=x[0];
    }

Ora si tratta di controllare se l'ipotesi è ancora valida ad ogni passo del ciclo. Quando si analizza un elemento x[i] del vettore, possono presentarsi tre situazioni:

  1. x[i] è minore sia di max che di sec: in questo caso, l'ipotesi che max e sec siano i due massimi elementi del vettore non è stata smentita;
  2. x[i] è maggiore del secondo ma minore del massimo: l'ipotesi che max sia il massimo elemento del vettore continua a valore, ma non vale più l'ipotesi che sec sia il secondo; infatti, il massimo è max, ma il secondo trovato finora è x[i]; quindi, si copia il valore di x[i] al posto di sec;
  3. x[i] è maggiore sia di max che di sec; in questa situazione, i massimi elementi del vettore trovati finora sono, in ordine: x[i], max e sec; quindi, i due elementi maggiori sono x[i] e max. In altre parole, il nuovo massimo è x[i] mentre il nuovo secondo è max; quindi, nella variabile max ci va messo il valore di x[i], mentre in sec ci va il vecchio valore di max.

Il codice che realizza un ciclo fatto in questo modo è il seguente:

    for(i=2; i<=x.length-1; i=i+1) {

                /* x[i] e' maggiore del massimo corrente */
      if( x[i]>max ) { 
        sec=max;
        max=x[i];
      }

		/* x[i] e' compreso fra il massimo corrente e il secondo */
      else if( x[i]<=max && x[i]>sec ) {
        sec=x[i];
      }
    }

Alla fine della esecuzione del ciclo, le variabili max e sec contengono i due massimi elementi del vettore, in ordine. Questo è garantito dal fatto che, ad ogni passo, o l'ipotesi precedente è stata confermata, oppure una eccezione ha permesso di modificare l'ipotesi per tenere conto di un nuovo elemento del vettore.

Il codice completo del programma MassimoSecondo.java è qui sotto.

/*
  Trova l'elemento massimo di un vettore, e poi quello
  subito inferiore
*/

class MassimoSecondo {
  public static void main(String[] args) {
    int x[]={5, 38, 71, 4, 37, 70, 3, 36, 69, 2, 35, 68, 1, 34, 67, 0, 33, 66, 99, 32, 65};
    int max, sec;
    int i;

		/* assumiamo che i due elementi massimi siano i primi due */
    if ( x[0]>x[1] ) {
      max=x[0];
      sec=x[1];
    }
    else {
      max=x[1];
      sec=x[0];
    }

		/* scansione del vettore */
    for(i=2; i<=x.length-1; i=i+1) {

		/* se un elemento del vettore e' maggiore del massimo,
		   allora e' il nuovo massimo, e il vecchio massimo
		   diventa il secondo */
      if( x[i]>max ) { 
        sec=max;
        max=x[i];
      }

		/* se un elemento non e' maggiore del massimo ma e' maggiore
		   del secondo, allora e' il nuovo secondo */
      else if( x[i]<=max && x[i]>sec ) {
        sec=x[i];
      }
    }

    System.out.println("Massimo= "+max);
    System.out.println("Secondo= "+sec);
  }
}