程序在计算中忽略文件中的最后一行
Program ignoring the last row in the file in calculation
我有一个包含如下数据的文本文件 (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
我的代码解析该文件并对其进行一些计算。
但是,在调用另一个名为 getTestAvg()
的方法(计算列均值)的方法 arrangeList()
中,程序忽略了 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;
}
}
这是我应该得到的数字(顶部)与我的程序输出的数字(底部)的比较。
在行
double[][] tests = new double[N][N];
函数 arrangeList
您将测试数组设置为 N X N。
我相信你应该这样做
double[][] tests = new double[M][N];
这只是一个建议,因为在您的代码中似乎 M = 学生人数,N = 测试次数,与您在问题中所写的不同。
一般来说,您应该复习所有方法 arrangeList
,也可能 getTestAvg
(在 N 上循环,而不是在 M 上循环),因为变量 len
上的循环旨在用于N X N数组,实际情况并非如此。
您需要考虑不同的尺寸。我认为你主要想要测试的数量(不是学生),但你不能只对两个索引范围使用 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);
}
}
请注意,它不仅调整了数组的大小,而且还更改了循环条件,以便为内循环和外循环循环适当的数量。
正如其他回复所述,您的变量和循环存在很大问题。我现在将 N 更改为# of students,将 M 更改为# of tests,如您在问题中所述。
下次,也许尝试改进您的变量命名,这样您就不会感到困惑。 (例如,如果您喜欢简短的变量名称,则为 s
(学生)和 t
(测试)切换掉 n
和 m
。
现在应该可以了。只需检查您的代码以查看更改。
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;
}
}
我有一个包含如下数据的文本文件 (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
我的代码解析该文件并对其进行一些计算。
但是,在调用另一个名为 getTestAvg()
的方法(计算列均值)的方法 arrangeList()
中,程序忽略了 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;
}
}
这是我应该得到的数字(顶部)与我的程序输出的数字(底部)的比较。
在行
double[][] tests = new double[N][N];
函数 arrangeList
您将测试数组设置为 N X N。
我相信你应该这样做
double[][] tests = new double[M][N];
这只是一个建议,因为在您的代码中似乎 M = 学生人数,N = 测试次数,与您在问题中所写的不同。
一般来说,您应该复习所有方法 arrangeList
,也可能 getTestAvg
(在 N 上循环,而不是在 M 上循环),因为变量 len
上的循环旨在用于N X N数组,实际情况并非如此。
您需要考虑不同的尺寸。我认为你主要想要测试的数量(不是学生),但你不能只对两个索引范围使用 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);
}
}
请注意,它不仅调整了数组的大小,而且还更改了循环条件,以便为内循环和外循环循环适当的数量。
正如其他回复所述,您的变量和循环存在很大问题。我现在将 N 更改为# of students,将 M 更改为# of tests,如您在问题中所述。
下次,也许尝试改进您的变量命名,这样您就不会感到困惑。 (例如,如果您喜欢简短的变量名称,则为 s
(学生)和 t
(测试)切换掉 n
和 m
。
现在应该可以了。只需检查您的代码以查看更改。
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;
}
}