Higher and lower value

Asked

Viewed 2,832 times

1

Make a program that takes a set of integer and positive values and calculates and shows the highest and lowest value of the set. (To close the input, zero must be entered).

I know that the part of the lowest value is wrong, because the doubt is exactly getting the lowest value, the highest 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);

    }

}

1 answer

4


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

-1.0 -10.0 -7.0 0

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

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

  1. the reading of the first paragraph shall be considered special
  2. use some markup to indicate that it is the first reading and make the special treatment, how to use the wrapper Double to store the maximum and minimum values of the list initialized with null
  3. store in a list and then treat as 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 initialized the basic values and only then I went to find out how to update to new values.

Note that due to the principle of good ordination, if a > b and b > c, then I have to a > c. So there is no way I can update the higher value and at the same time update the lower value. So due to this, I put a else if instead of always checking whether to update the lowest oi value.

Marking of 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 is absurdly similar. Only 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 for a 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 java 8

I could use several alternatives, but the fastest is using the DoubleSummaryStatistics. For this I will use a special collector: Collectors.summarizingDouble. I’m adapting that answer of 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);

Browser other questions tagged

You are not signed in. Login or sign up in order to post.