Higher and lower value

1
  

Make a program that receives a set of integer and positive values and that calculates and shows the highest and lowest value of the set. (To close the entry, you must enter the value zero.)

I know the part of the smallest value is wrong, because the question is exactly to get the smallest value, the biggest value is correct.

package exercices2;

import java.util.Scanner;

public class MaiorEMenor {

    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        double valor = 1;
        double valorMaior = 0;
        double valorMenor = 0;
        for(;valor!=0;) {
            System.out.println("Digite os valores (0 para parar):");
            valor = input.nextDouble();
            if(valor > valorMaior && valor!=0) {
                valorMaior = valor;

            }
            if(valor < valorMenor && valor!=0) {
                valorMenor = valor;
            }   
        }
        System.out.println("Maior valor: "+ valorMaior);
        System.out.println("Menor valor: "+ valorMenor);

    }

}
    
asked by anonymous 23.03.2018 / 04:04

1 answer

4

What happened to your wrong code? You set bad starting values. Note that in the statement it was not defined that the numbers will be strictly positive. The following entry would give the wrong result for valorMaior but right for valorMenor :

-1.0 -10.0 -7.0 0

Why will you give wrong value? Because you are taking an value out of the list and using it as a basis.

Without using Java 8, the solution would be to get the first number as something special. I see three alternatives:

  • reading the first number is considered special
  • Use some markup to indicate that it is the first read and make the special treatment, such as using the wrapper Double to save the maximum and minimum values of the list initialized with null
  • store in a list and then treat it as if it were in case 1
  • Special first reading

    Scanner input = new Scanner(System.in);
    double valorLido = input.nextDouble();
    double menor, maior;
    menor = maior = valorLido; // inicializo ambos os valores maior e menor com o primeiro valor lido
    while (valorLido != 0) {
      valorLido = input.nextDouble();
      if (valorLido != 0) {
        if (valorLido > maior) {
          maior = valorLido;
        } else if (valorLido < menor) {
           menor = valorLido;
        }
      }
    }
    
    System.out.println("maior " + maior);
    System.out.println("menor " + menor);
    

    I treated the first reading in a special way. I started the basic values and only then went after knowing how to upgrade to new values.

    Note that due to the principle of good ordering, if a > b and b > c , then I have a > c . So I can not update the larger value and at the same time update the smaller value. So, because of this, I put a else if instead of always checking to see if it should update the smallest value oi no.

    Marking the first reading via wrapper
    Scanner input = new Scanner(System.in);
    Double menor, maior;
    menor = maior = null;
    
    while (true) {
      double valorLido = input.nextDouble();
      if (valorLido == 0) {
        break;
      }
      if (maior == null) {
        // marcação da primeira leitura, devo atualizar ambos os valores de maior e menor
        maior = menor = valorLido;
      } else if (valorLido > maior) {
        // já caiu no caso else, então não é primeira leitura
        maior = valorLido;
      } else if (valorLido < menor) {
        menor = valorLido;
      }
    }
    System.out.println("maior " + maior);
    System.out.println("menor " + menor);
    

    Marking the first reading using a boolean

    It's absurdly similar. But here I must initialize with arbitrary values (I chose NaN ) the values of maior and menor .

    Scanner input = new Scanner(System.in);
    double menor, maior;
    menor = maior = Double.NaN;
    boolean primeiraLeitura = true;
    
    while (true) {
      double valorLido = input.nextDouble();
      if (valorLido == 0) {
        break;
      }
      if (primeiraLeitura) {
        // marcação da primeira leitura, devo atualizar ambos os valores de maior e menor
        maior = menor = valorLido;
        primeiraLeitura = false; // marcando para não ler novamente
      } else if (valorLido > maior) {
        // já caiu no caso else, então não é primeira leitura
        maior = valorLido;
      } else if (valorLido < menor) {
        menor = valorLido;
      }
    }
    System.out.println("maior " + maior);
    System.out.println("menor " + menor);
    

    Store in a list

    This alternative is trivial. Play the reading to ArrayList and then treat the values within it.

    Scanner input = new Scanner(System.in);
    ArrayList<Double> lista = new ArrayList<>();
    
    double valorLido;
    while (true) {
      valorLido = input.nextDouble();
      if (valorLido == 0) {
        break;
      }
      lista.add(valorLido);
    }
    double maior, menor;
    maior = menor = lista.get(0);
    for (Double valor: lista) {
      if (valor > maior) {
        maior = valor;
      } else if (valor < menor) {
        menor = valor;
      }
    }
    System.out.println("maior " + maior);
    System.out.println("menor " + menor);
    

    Using stream API of Java 8

    I could use several alternatives, but the fastest is using DoubleSummaryStatistics . For this I will use a special sink: Collectors.summarizingDouble ". I'm adapting this from Stack Overflow International.

    Scanner input = new Scanner(System.in);
    ArrayList<Double> lista = new ArrayList<>();
    
    double valorLido;
    while (true) {
      valorLido = input.nextDouble();
      if (valorLido == 0) {
        break;
      }
      lista.add(valorLido);
    }
    DoubleSummaryStatistics summary = lista.stream().collect(Collectors.summarizingDouble(Double::doubleValue));
    double maior = summary.getMax();
    double menor = summary.getMin();
    System.out.println("maior " + maior);
    System.out.println("menor " + menor);
    
        
    23.03.2018 / 05:50