扫描值的简化方式?

时间:2019-04-28 19:37:11

标签: java

当前,我正在按4个考试成绩等级进行扫描,每个等级均针对已声明和初始化的自己的变量。我想知道是否有更好的方法可以减少混乱。请耐心等待,因为我目前在uni上的第一堂Java课上没有任何经验,所以我不希望解决方案变得非常复杂,至少不是但很容易理解。不知道它是否有帮助/有问题,但是我正在使用BlueJ作为我的IDE。

import java.util.*;

public class GradeCalculatorDriver
{
    public static void main(String [] args){
        String s1 = "student";//Declare student string variable;
        String s2;
        double exam1 = 0;//Declare and initalize variables.
        double exam2 = 0;//Declare and initalize variables.
        double exam3 = 0;//Declare and initalize variables.
        double exam4 = 0;//Declare and initalize variables.

        do{
            Scanner input = new Scanner(System.in);
            System.out.println("This program will calculate the average of 4 exam scores, and return the lowest, highest, and letter grade associated with the average");

            System.out.println("Please enter the name of the student");//Request student name and scans it into a string.
            String student = input.next();

            System.out.println("Please enter one exam score, then hit enter and repeat for following grades.");//Request exam scores and scan them into variables.
            exam1 = input.nextDouble();
            exam2 = input.nextDouble();
            exam3 = input.nextDouble();
            exam4 = input.nextDouble();

            double highest = GradeCalculator.high(exam1, exam2, exam3, exam4);//Calls highest grade method.
            double lowest = GradeCalculator.low(exam1, exam2, exam3, exam4);//Calls lowest grade method.
            double average = GradeCalculator.avg(exam1, exam2, exam3, exam4);//Calls average grade method.
            char letterGrade = GradeCalculator.letter(exam1, exam2, exam3, exam4);//Calls letter grade method.

            System.out.printf("The highest exam score is : %.2f " + highest);//Displays highest grade.
            System.out.printf("The lowest exam score is : %.2f " + lowest);//Displays lowest grade.
            System.out.printf("The average exam score is : %.2f " + average);//Displays average grade.
            System.out.print("The letter grade is " + letterGrade);//Displays letter grade associated with average.

            System.out.println("Would you like to enter another students grades? (yes/no)");//asks the user if they would like to calculate another factorial.
            s2 = input.next();

        } while (s2.equalsIgnoreCase("YES"));//checks to see what the users response was. 
        System.out.print("Thank you for using my program!");//Ending statement.
    }
}


public class GradeCalculator{

public static double high(double exam1, double exam2, double exam3, double exam4){//Calculates the highest exam score entered.
        double highest;//Declare and initilize variable.

        highest = Math.max(Math.max(Math.max(exam1, exam2), exam3), exam4);

        return highest;//Returns highest exam score.
    }

    public static double low(double exam1, double exam2, double exam3, double exam4){//Calculates the lowest exam score entered.
        double lowest = 0;//Declare and initilize variable.

        lowest = Math.min(Math.min(Math.min(exam1, exam2), exam3), exam4);

        return lowest;//Returns highest exam score.
    }

    public static double avg (double exam1, double exam2, double exam3, double exam4){//Calculates the average exam score.
        double average;//Declare variable.
        double count = 4;//Declare and initilize variable.

        average = ((exam1 + exam2 + exam3 + exam4) / count);

        return average;//Returns average grade.
    }


        public static char letter (double exam1, double exam2, double exam3, double exam4){//Calculates the letterGrade based on the average exam score.
            char letterGrade;//Declare and initilize variable.
            double count = 4;//Declare and initilize variable.
            double average = ((exam1 + exam2 + exam3 + exam4) / count);//declare and calculate average score.

            if (average >= 90)
                letterGrade = 'A';
            else if (average >= 80)
                letterGrade = 'B';
            else if (average >= 70)
                letterGrade = 'C';
            else if (average >= 60)
                letterGrade = 'D';
            else 
                letterGrade = 'E';

            return letterGrade;//Returns letter grade.
        }
    }

2 个答案:

答案 0 :(得分:1)

您可以使用List<Double> scores = new ArrayList<>()来保存考试成绩值并减少代码混乱。然后,当您从用户输入中添加新的考试分数时,您将为每个输入值调用scores.add(input.nextDouble())

答案 1 :(得分:0)

好吧,在我看来,如果这是您的第一招(可以这么说)(可以这么说),那么您就可以成为一名成功的Java程序员。至于减少混乱,我想这取决于您已经学到的东西,例如已经介绍的Java方法和语句,现在可以使用它们来创建应用程序来完成手头的任务。确实没有办法知道您的学习程度,因此以下提供的建议仅应被定义为单纯的建议:

您当前的模型没有什么问题,只有一些小错误,这些小错误会生成 MissingFormatArgumentException 并且在代码行之内:

System.out.printf("The highest exam score is : %.2f " + highest);
System.out.printf("The lowest exam score is : %.2f " + lowest);
System.out.printf("The average exam score is : %.2f " + average);

您的代码中的任何错误均应首先修复。上面的每行代码都包含一个错误,这仅仅是因为没有为格式说明符(%.2f)提供参数。这是因为您在要使用逗号分隔符的位置放置了加号(+),以表示用于表示%。2f 的参数。在这种情况下, + 会将以下字符串或变量内容附加到前面的字符串中。该代码应为:

System.out.printf("The highest exam score is : %.2f ", highest);
System.out.printf("The lowest exam score is : %.2f ", lowest);
System.out.printf("The average exam score is : %.2f ", average);

或仅使用String.format()方法:

System.out.println("The lowest exam score is:  " + String.format("%.2f",lowest));
System.out.println("The highest exam score is: " + String.format("%.2f", highest)); 
System.out.println("The average exam score is: " + String.format("%.2f", average));

不应在 do / while 循环的每次迭代中都声明Scanner。将此声明放在 do / while 代码块上方,以免打开不必要的Scanner实例。

不需要在 do / while 循环的每次迭代中完成应用程序功能的解释。将此消息移到执行/执行代码块上方。

在提示用户输入时,请勿使用Scanner#next()方法,除非您期望接收字符串标记。有时,使用Scanner#nextLine()方法更容易。我认为它可以提供更大的灵活性,并为您提供更好的机会来防止可能的异常(如果可以防止异常,请不要依赖异常)。

信不信由你...有时候注释可能是代码混乱的最大来源。绝对没有必要评论显而易见的内容。是的,我可能这样做了,但这只是为了解释代码。预计将被删除。

您可以摆脱以下代码行:String s1 = "student";//Declare student string variable;。您似乎没有在任何地方使用此变量。

正如已经建议的那样,可以使用数组或集合机制来保存学生分数,但是从减少混乱的意义上讲,它不会仅获得4个分数,但会获得更多分数,因此是处理分数的一种好方法这部分代码。在任何情况下,如果您的课程已经涵盖了数组和/或 ArrayLists 的使用,这仍然是一个好方法。不知道您的要求是否仅使用 所学知识。无论如何....

要利用数组存储学生分数,您还需要修改 GradeCalculator 类中的所有方法。这本身将消除参数混乱,因为您只需要一个参数,而不是每个方法使用4个参数即可。如果要使用数组,则该类中的方法可能类似于以下内容:

public class GradeCalculator {
    public static double high(double[] exams) {//Calculates the highest exam score entered.
        double highest = 0.0d;//Declare and initilize variable to 0.0
        for (int i = 0; i < exams.length; i++) {
            if (exams[i] > highest) {
                highest = exams[i];
            }
        }
        return highest;//Returns highest exam score.
    }

    public static double low(double[] exams) {//Calculates the lowest exam score entered.
        double lowest = exams[0];
        for (int i = 0; i < exams.length; i++) {
            if (exams[i] < lowest) {
                lowest = exams[i];
            }
        }
        return lowest;//Returns lowest exam score.
    }

    public static double avg(double[] exams) {//Calculates the average exam score.
        double average = 0.0d;  //Declare variable.
        double sum = 0.0d;
        for (int i = 0; i < exams.length; i++) {
            sum+= exams[i];
        }
        average = sum / exams.length;
        return average; //Returns average grade.
    }

    //Calculates the letter-Grade based on the average exam score.
    public static char letter(double average) {
        char letterGrade;//Declare and initilize variable.
        if (average >= 90) {
            letterGrade = 'A';
        }
        else if (average >= 80) {
            letterGrade = 'B';
        }
        else if (average >= 70) {
            letterGrade = 'C';
        }
        else if (average >= 60) {
            letterGrade = 'D';
        }
        else {
            letterGrade = 'E';
        }
        return letterGrade; //Returns letter grade.
    }
}

letter()方法只需要一个参数,而不是您必须提供的4个参数,这是从 average()方法返回的值。您会看到,您无需在 letter()方法中再次计算平均值,因为您已经有一个已经做到并已经完成的方法。只需将已经计算的平均值传递给 letter()方法。

要用用户输入来填充数组,最好使用某种循环来执行任务,但是再次取决于您希望用户如何提供该信息(例如测试分数)。也许您希望用户通过用空格分隔每个分数来提供来自单个输入的所有分数:

Please enter all student scores (separated with a space):
65 112 75 88

此代码可能如下所示:

String s2;
boolean invalidEntry;
String LS = System.lineSeparator();
double[] exams; // Declare Array
Scanner input = new Scanner(System.in);
System.out.println("This program will calculate the average of any number of "
            + LS + "desired exam scores and return the lowest,  highest, and "
            + LS + "letter grade associated with that determined average." + LS);

do {
    s2 = "";
    invalidEntry = false;
    // Request Student Name
    System.out.println("Please enter the name of the student (nothing to exit):");
    String student = input.nextLine();
    if (student.equals("")) { break; }

    // Request exam scores
    System.out.println("Please enter all student scores (each separated with a space): ");
    String scores = input.nextLine();
    // If nothing was supplied break out of loop 
    if (scores.equals("")) { 
        invalidEntry = true;
        break; 
    } 
    String[] scoresArray = scores.split("\\s+");  // Split the input into single scores (regex "\\s+" is used to split on one or more whitespaces).
    exams = new double[scoresArray.length]; // Initalize Array.
    // Convert scores to double data type...
    for (int i = 0; i < scoresArray.length; i++) {
        /* Is the string value actually a numerical signed
           or unsigned integer or double type value. Save
           this Regular Expression. It's handy to have.  */
        if (scoresArray[i].matches("-?\\d+(\\.\\d+)?")) {
            exams[i] = Double.parseDouble(scoresArray[i]);
        }
        else {
            System.out.println("One or more of the Scores supplied are invalid! "
                             + "Enter Student Scores again!" + LS);
            invalidEntry = true;
            break;
        }
    }
    if (invalidEntry) { continue; } // Redo loop on Invalid Entry

    double highest = high(exams);
    double lowest = low(exams);
    double average = avg(exams);
    char letterGrade = letter(average);

    System.out.println(LS + "Results For Student:       " + student); 
    System.out.println("From " + String.format("%02d" , exams.length) + 
                       " exam scores:       " + 
                       Arrays.toString(exams).replaceAll("[\\[\\]]", ""));
    System.out.println("The lowest exam score is:  " + String.format("%.2f",lowest));
    System.out.println("The highest exam score is: " + String.format("%.2f", highest)); 
    System.out.println("The average exam score is: " + String.format("%.2f", average));
    System.out.println("The letter grade is:       " + letterGrade + LS);

    while (s2.equals("")) {
        System.out.println("Would you like to enter another Students Scores? (yes/no)");
        s2 = input.nextLine();
        if (!s2.equalsIgnoreCase("yes") && !s2.equalsIgnoreCase("no")) {
            System.out.println("Invalid Response! 'Yes' or 'No' only!");
            s2 = "";
        }
    }

} while (s2.equalsIgnoreCase("yes") || invalidEntry);
System.out.println("Thank you for using my program!");

有时候,如上面的代码所示,对于用户来说,在一行上输入所有分数更加容易,但是,您为应用程序的运行设置了规则。如果您想单独输入每个分数,那就这样吧。代码可能看起来像这样:

String s2;
int indexCounter; // Declare an index counter for array.
boolean invalidEntry;
String LS = System.lineSeparator();
double[] exams; //Declare Array.
Scanner input = new Scanner(System.in);
System.out.println("This program will calculate the average of any number of "
            + LS + "desired exam scores and return the lowest,  highest, and "
            + LS + "letter grade associated with that determined average." + LS);

do {
    s2 = "";
    indexCounter = 0; // Set index counter to 0
    invalidEntry = false;

    // Request Student Name
    System.out.println("Please enter the name of the Student (nothing to exit):");
    String student = input.nextLine();
    if (student.equals("")) { break; }

    // Get number of Scores to enter from User
    int numberOfScores = 0;
    while (numberOfScores == 0) {
        System.out.println("Please enter the number of scores you wish to enter:");
        String numScores = input.nextLine();
        // Is the value supplied a String Integer value
        if (!numScores.matches("\\d+")) {
            System.out.println("Invalid number of scores provided! Try Again..." + LS);
            continue;
        }
        numberOfScores = Integer.parseInt(numScores);
    }
    exams = new double[numberOfScores]; // Initialize Array

    // Request exam scores
    while (indexCounter < numberOfScores) {
        System.out.println("Please enter exam score #" + (indexCounter + 1) + 
                " then hit enter: ");
        exams[indexCounter] = input.nextDouble();
        input.nextLine();  // Clear the scanner buffer
        indexCounter++;
    }

    double highest = high(exams);
    double lowest = low(exams);
    double average = avg(exams);
    char letterGrade = letter(average);

    System.out.println(LS + "Results For Student:       " + student);
    System.out.println("From " + String.format("%02d" , exams.length) + 
                       " exam scores:       " + 
                       Arrays.toString(exams).replaceAll("[\\[\\]]", ""));
    System.out.println("The lowest exam score is:  " + String.format("%.2f",lowest));
    System.out.println("The highest exam score is: " + String.format("%.2f", highest)); 
    System.out.println("The average exam score is: " + String.format("%.2f", average));
    System.out.println("The letter grade is:       " + letterGrade + LS);

    while (s2.equals("")) {
        System.out.println("Would you like to enter another Student's Scores? (yes/no)");
        s2 = input.nextLine();
        if (!s2.equalsIgnoreCase("YES") && !s2.equalsIgnoreCase("NO")) {
            System.out.println("Invalid Response! 'Yes' or 'No' only!");
            s2 = "";
        }
    }
} while (s2.equalsIgnoreCase("YES") || invalidEntry);
System.out.println("Thank you for using my program!");

您将注意到上面的某些代码利用了Regular Expressions,例如"\\s+""\\d+""[\\[\\]]"甚至是"-?\\d+(\\.\\d+)?"。学习如何利用Java的 java.util.regex 包进行模式匹配,从来就不晚。它可以迅速成为您的密友,一旦学会,您就会发现自己一直在使用它。要测试正则表达式并获得特定表达式的解释,可以使用RegEx101.com网站,例如:this regex