Detectar uma determinada entrada do usuário sem primeiro processá-la em um loop while

Sep 30 2020

Eu tenho esse programa onde o usuário insere x quantidade de notas, então o programa divide a soma das notas pelo número de entradas feitas. Ele também deve encontrar as notas mais altas e mais baixas inseridas. Quando o usuário termina, ele digita -1 para encerrar o programa. No entanto, estou tendo alguns problemas com isso.

  1. O programa adiciona -1 à média, o que distorce todos os meus resultados.
  2. Não consigo descobrir como calcular o valor mínimo da lista. Sempre conta -1 como o valor mínimo.

Aqui está o código abaixo:

import java.util.Scanner;

public class Lab4_EnteringGrades
{
    public static void main (String a[]) 
    {    
         Scanner kb = new Scanner(System.in); 
  
         double average = 0;
         double gradesSum = 0;
         int grade = 0; 
         int numTests = 0;
         int maxValue = 0;
         int minValue = 0;
 
        
         while (grade != -1)
         {
             gradesSum += grade; 
             numTests += 1; 
             average = gradesSum / numTests;
        
             System.out.print("Enter a grade: ");
             grade = kb.nextInt();
              
             while ((grade < -1) || (grade > 100))
             {
                 System.out.println("Invalid grade.");
                 System.out.print("Enter a grade: ");
                 grade = kb.nextInt();
             }     
     
             if (grade > maxValue)
                 maxValue = grade;
         
             if (grade < maxValue)
                 minValue = grade;
          }
     
         System.out.printf("\nTotal number of tests: %d", numTests);
         System.out.printf("\nThe average is %.1f", average);
         System.out.printf("\nThe max value is %d", maxValue);
         System.out.printf("\nThe min value is %d", minValue);
    }
}

  
  

Respostas

4 Anon Sep 30 2020 at 07:30

Eu fiz algumas mudanças -

  1. A inicialização de minValuee maxValue, em seu código original, minValueera -1 e gradenão poderia ser menor que -1, portanto, você sempre viu minValuecomo -1. Em geral, se você quiser os valores mínimo e máximo, é melhor inicializar como fiz aqui.

  2. Movida a lógica de cálculo grade, averageDEPOIS do usuário entrar gradeno para não atrapalhar o average.

  3. Seu código original era:

if (nota <maxValue)

Eu mudei isso para ser if (grade < minValue). Eu acredito que foi um erro de digitação.

import java.util.Scanner;

public class Lab4_EnteringGrades {
    public static void main (String a[])
    {
        Scanner kb = new Scanner(System.in);

        double average = 0;
        double gradesSum = 0;
        int grade = 0;
        int numTests = 0;
        int maxValue = Integer.MIN_VALUE;
        int minValue = Integer.MAX_VALUE;


        while (true)
        {

            System.out.print("Enter a grade: ");
            grade = kb.nextInt();

            while ((grade < -1) || (grade > 100))
            {
                System.out.println("Invalid grade.");
                System.out.print("Enter a grade: ");
                grade = kb.nextInt();
            }
            if (grade == -1) {
                break;
            }

            gradesSum += grade;
            numTests += 1;
            average = gradesSum / numTests;


            if (grade > maxValue)
                maxValue = grade;

            if (grade < minValue)
                minValue = grade;
        }

        System.out.printf("\nTotal number of tests: %d", numTests);
        System.out.printf("\nThe average is %.1f", average);
        System.out.printf("\nThe max value is %d", maxValue);
        System.out.printf("\nThe min value is %d", minValue);
    } }
3 thatotherguy Sep 30 2020 at 07:25

Os problemas são que

  1. Você faz gradesSum += grade;antes de ler a primeira série, quando gradeainda está 0.
  2. Você faz if (grade < maxValue)depois que o usuário entrou grade=-1;, portanto sempre descobrirá que -1é menor.
  3. Você compara a nota maxValuepara verificar o máximo e o mínimo
  4. Desde que você inicializou minValue=0, você nunca encontrará um valor menor (exceto -1), então você deve inicializá-lo para algo maior

Você pode mover todo o código que processa a nota até depois de lê-lo e, em seguida, breakse o usuário inserir -1:

import java.util.Scanner;

public class Lab4_EnteringGrades
{
public static void main (String a[])
  {
  Scanner kb = new Scanner(System.in);

  double average = 0;
  double gradesSum = 0;
  int grade = 0;
  int numTests = 0;
  int maxValue = 0;
  int minValue = 101;

  while (true)
     {
     System.out.print("Enter a grade: ");
     grade = kb.nextInt();

     while ((grade < -1) || (grade > 100))
        {
        System.out.println("Invalid grade.");
        System.out.print("Enter a grade: ");
        grade = kb.nextInt();
        }

     // Stop if the user entered -1
     if (grade == -1) break;

     gradesSum += grade;
     numTests += 1;
     average = gradesSum / numTests;

     if (grade > maxValue)
        maxValue = grade;

     if (grade < minValue)
        minValue = grade;
     }

  System.out.printf("\nTotal number of tests: %d", numTests);
  System.out.printf("\nThe average is %.1f", average);
  System.out.printf("\nThe max value is %d", maxValue);
  System.out.printf("\nThe min value is %d", minValue);
  }
}

O while(true) { if(..) break; }é um pouco estranho embora. Você pode melhorar o código ainda mais criando uma função separada para ler a entrada:

import java.util.Scanner;

public class Lab4_EnteringGrades
{
  public static int readGrade(Scanner kb) {
    System.out.print("Enter a grade: ");
    int grade = kb.nextInt();

    while ((grade < -1) || (grade > 100))
    {
      System.out.println("Invalid grade.");
      System.out.print("Enter a grade: ");
      grade = kb.nextInt();
    }
    return grade;
  }

  public static void main (String a[])
  {
    Scanner kb = new Scanner(System.in);

    double average;
    double gradesSum = 0;
    int grade;
    int numTests = 0;
    int maxValue = Integer.MIN_VALUE;
    int minValue = Integer.MAX_VALUE;

    // Common idiom for reading a grade until it's -1
    while ((grade = readGrade(kb)) != -1) {
      gradesSum += grade;
      numTests += 1;

      if (grade > maxValue)
        maxValue = grade;

      if (grade < minValue)
        minValue = grade;
    }
    // Consider handling the case of numTests == 0
    average = gradesSum / numTests;

    System.out.printf("\nTotal number of tests: %d", numTests);
    System.out.printf("\nThe average is %.1f", average);
    System.out.printf("\nThe max value is %d", maxValue);
    System.out.printf("\nThe min value is %d", minValue);
  }
}