【问题标题】:Program ignoring the last row in the file in calculation程序在计算中忽略文件中的最后一行
【发布时间】:2020-12-17 02:09:32
【问题描述】:

我有一个包含如下数据的文本文件 (TestData.txt):

Name|Test1|Test2|Test3|Test4|Test5|Test6|Test7|Test8|Test9|Test10
John Smith|82|89|90|78|89|96|75|88|90|96
Jane Doe|90|92|93|90|89|84|97|91|87|91
Joseph Cruz|68|74|78|81|79|86|80|81|82|87
Suzanne Nguyen|79|83|85|89|81|79|86|92|87|88
Richard Perez|100|84|73|81|92|84|95|96|95|100
Ivan Dyer|77|91|90|75|97|94|76|89|90|92
Craig Palmer|91|84|98|89|82|75|78|96|100|97
Madeline Rogers|75|79|78|93|91|76|80|88|100|81
Chelsea Roxas|87|94|89|96|95|85|88|92|86|86
Jasper Bautista|100|83|93|100|98|97|96|97|97|98
Tyler Perez|82|89|90|78|89|96|75|88|90|96

我的代码解析文件并用它做一些计算。

但是,在方法 arrangeList() 中调用另一个名为 getTestAvg() 的方法(计算列均值),程序会忽略 Tyler Perez 的分数。

我注意到我得到的结果不准确,所以我去打印了包含所有测试分数的整个二维数组,但最后一列找不到了。

我的整个代码如下,我希望有人能指出是什么原因造成的。

每当我尝试切换 N(学生数量)和 M(测试数量)以查看会发生什么时,我都会不断收到 IndexOutOfBounds 错误。一开始我有 10 个学生和 10 个测试,所有的计算都是正确的,但是当我添加另一个学生时,计算变得不准确。

如果我的代码没有像我不是经验丰富的程序员那样精心设计,我提前道歉。

import java.util.*;
import java.io.*;

public class TestAverages
{
  private static int[] grades;
  private static int[] testTotal;
  private static int N;
  private static double classTotal;
  private static int M;
  
  public static void main(String[] args) throws FileNotFoundException
  {
    File input = new File("TestData.txt");
    Scanner in = new Scanner(input);
    parseFile(in); 
  }
  
  
  public static void parseFile(Scanner in) throws FileNotFoundException
  {
    TestAverages t = new TestAverages();
    in.nextLine(); 
    double total = 0.0;
    
    ArrayList<Double> testScores = new ArrayList<Double>();
    int index = 0;
    while(in.hasNextLine())
    {
      String line = in.nextLine();
      String[] data = line.split("\\|");
      String name = data[0];
      
      grades = new int[data.length - 1];
      N = grades.length;

      for(int i = 0; i < N; i++){
        grades[i] = Integer.parseInt(data[i + 1]);
        testScores.add((double)grades[i]);
      }
      
      System.out.println(name + "\t");
      System.out.println("Student Average: " + t.getStudentAvg(grades) + "%\n");
      total += t.getStudentAvg(grades);
      
      M++;
      
    }
    t.arrangeList(testScores);
    System.out.printf("\nClass Average: %.1f%%\n", t.getClassAvg(total));
    

    
  }
  
  
  public double getStudentAvg(int[] grades)
  {
    double total = 0.0;
    double avg = 0.0;
    int N = grades.length;
    
    for(int i = 0; i < N; i++){
      total += grades[i];}
    
    avg = total / N;
    
    return avg;
  }
  
  
  public double getClassAvg(double total)
  {
    double classAvg = total / M;
    
    return classAvg;
  }
  

  public double[][] arrangeList(ArrayList testScores)
  {
    double[][] tests = new double[N][N];
    
    int len = tests.length;
    for(int i = 0; i < len; i++)
    {
      for(int j = 0; j < len; j++)
      {
        tests[i][j] = (Double) testScores.get(i*N + j);
      }
    }

    for(int i = 0; i < len; i++)
    {
      double avg = getTestAvg(tests, i);
      System.out.printf("\nTest " + (i + 1) + " Average: %.1f%%\n", avg);
    }
    return tests;
  }
  

  public double getTestAvg(double[][] testScores, int index)
  {
    double testAvg = 0.0;
    for(int i = 0; i < N; i++)
    {
      testAvg += testScores[i][index]; 
    }

    return testAvg / N;
  }
}

这是我应该得到的数字(上)与我的程序输出(下)的比较。

【问题讨论】:

    标签: java arrays for-loop average mean


    【解决方案1】:

    正如其他回复所述,您的变量和循环存在很大问题。我现在将 N 更改为 # of students 并将 M 更改为 # of tests ,就像您在问题中所说的那样。

    下一次,也许尝试改进你的变量命名,这样你就不会感到困惑了。 (例如,如果您喜欢较短的变量名,请将 nm 换成 s(学生)和 t(测试)。

    现在应该可以了。只需检查您的代码即可查看更改。

    import java.util.*;
    import java.io.*;
    
    public class TestAverages {
        private static int[] grades;
        private static int n = 0; // amount of students
        private static int m; // amount of tests
    
        public static void main(String[] args) throws FileNotFoundException {
            File input = new File("TestData.txt");
            Scanner in = new Scanner(input);
            parseFile(in);
        }
    
        public static void parseFile(Scanner in) throws FileNotFoundException {
            TestAverages t = new TestAverages();
            in.nextLine();
            double total = 0.0;
    
            ArrayList<Double> testScores = new ArrayList<Double>();
            while (in.hasNextLine()) {
                String line = in.nextLine();
                String[] data = line.split("\\|");
                String name = data[0];
    
                grades = new int[data.length - 1];
                m = grades.length;
    
                for (int i = 0; i < m; i++) {
                    grades[i] = Integer.parseInt(data[i + 1]);
                    testScores.add((double) grades[i]);
                }
    
                System.out.println(name + "\t");
                System.out.println("Student Average: " + t.getStudentAvg(grades) + "%\n");
                total += t.getStudentAvg(grades);
    
                n++;
            }
            t.arrangeList(testScores);
            System.out.printf("\nClass Average: %.1f%%\n", t.getClassAvg(total));
        }
    
        public double getStudentAvg(int[] grades) {
            double total = 0.0;
            double avg = 0.0;
    
            for (int i = 0; i < grades.length; i++) {
                total += grades[i];
            }
    
            avg = total / grades.length;
    
            return avg;
        }
    
        public double getClassAvg(double total) {
            double classAvg = total / n;
    
            return classAvg;
        }
    
        public double[][] arrangeList(ArrayList<Double> testScores) {
            double[][] tests = new double[n][m];
    
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < m; j++) {
                    tests[i][j] = (Double) testScores.get(i * m + j);
                }
            }
    
            for (int i = 0; i < m; i++) {
                double avg = getTestAvg(tests, i);
                System.out.printf("\nTest " + (i + 1) + " Average: %.1f%%\n", avg);
            }
            return tests;
        }
    
        public double getTestAvg(double[][] testScores, int index) {
            double testAvg = 0.0;
            for (int i = 0; i < n; i++) {
                testAvg += testScores[i][index];
            }
    
            return testAvg / n;
        }
    }
    

    【讨论】:

    • 你是上帝派来的!我盯着屏幕看了好几个小时,试图弄清楚我可能错在哪里。非常感谢您的帮助,非常感谢您的帮助!
    【解决方案2】:

    您需要考虑不同的尺寸。我认为您主要需要 TESTS 的数量(而不是学生),但您不能只使用 len 作为两个索引范围。

        double[][] tests = new double[N][M];
        
        for(int i = 0; i < N; i++)
        {
          for(int j = 0; j < M; j++)
          {
            tests[i][j] = (Double) testScores.get(i*N + j);
          }
        }
    

    请注意,它不仅调整了数组的大小,还更改了循环条件以循环适当的内循环和外循环。

    【讨论】:

    • 感谢您的回复,但我仍然得到相同的输出。
    【解决方案3】:

    排队

      double[][] tests = new double[N][N];
    

    函数排列列表

    您将测试数组设为 N X N。

    我相信你应该做类似的事情

      double[][] tests = new double[M][N];
    

    这只是一个建议,因为在您的代码中似乎 M = 学生人数和 N = 测试次数,与您在问题中写的不同。

    一般而言,您应该查看所有方法 arrangeList 可能还有 getTestAvg(在 N 上循环,而不是 M),因为变量 len 上的循环用于 NXN 数组,但事实并非如此.

    【讨论】:

    • 不幸的是,我已经尝试过了。当我将其更改为 M 时,我收到 IndexOutOfBounds 错误。
    • 实际上您应该更改所有方法,因为它仅在一个索引上循环(在变量 len 上循环)。不幸的是,我无法查看所有内容,因为我现在没有编程环境
    • 感谢您抽出宝贵时间帮助我!我将所有变量混合在一起,@maloomeister 为我指明了正确的方向。再次感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-12-30
    • 1970-01-01
    • 1970-01-01
    • 2019-08-10
    • 1970-01-01
    • 1970-01-01
    • 2014-10-16
    相关资源
    最近更新 更多