英文:
Program ignoring the last row in the file in calculation
问题
以下是您的代码的翻译部分:
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("学生平均分: " + t.getStudentAvg(grades) + "%\n");
total += t.getStudentAvg(grades);
M++;
}
t.arrangeList(testScores);
System.out.printf("\n班级平均分: %.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("\n测试 " + (i + 1) + " 平均分: %.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;
}
}
希望这可以帮助您理解您的代码问题以及如何解决它们。如果您有任何进一步的问题,请随时提问。
英文:
I have a text file with data that looks like this (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
My code parses the file and does some calculations with it.
However, in the method arrangeList()
within which calls another method called getTestAvg()
(calculates column means), the program ignores Tyler Perez's scores.
I noticed that the results I am getting were inaccurate so I went and printed the whole 2d array with all the test scores and the last column is nowhere to be found.
My entire code is below and I hope someone could point out what causes this.
I keep getting an IndexOutOfBounds
error whenever I try to switch N (# of students) and M (# of tests) to see what happens. At first, I have 10 students and 10 tests, and all the calculations were correct, but when I added another student, the calculations became inaccurate.
I apologize in advance if my code isn't as well-designed as I'm not an experienced programmer.
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;
}
}
Here are the numbers I'm supposed to be getting (top) compared to what my program outputs (bottom).
答案1
得分: 3
如其他回复已经指出的那样,你在变量和循环方面确实遇到了问题。我现在将N更改为学生人数,将M更改为测试数量,与你在问题中所述一致。
下次尝试改进变量命名,这样你就不会感到困惑。(例如,如果你喜欢变量名简短,可以将n
和m
替换为s
(学生)和t
(测试))。
现在应该可以正常工作了。请与你的代码进行对比,查看更改。
import java.util.*;
import java.io.*;
public class TestAverages {
private static int[] grades;
private static int n = 0; // 学生人数
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>();
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("学生平均分: " + t.getStudentAvg(grades) + "%\n");
total += t.getStudentAvg(grades);
n++;
}
t.arrangeList(testScores);
System.out.printf("\n班级平均分: %.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("\n第 " + (i + 1) + " 个测试平均分: %.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;
}
}
英文:
As the other responses already stated, you had quite the issue with your variables and loops. I now changed N to # of students and M to # of tests to be as you stated in your question.
Next time, maybe try to improve your variable naming, so you don't get confused. (e.g. switch out n
and m
for s
(students) and t
(tests), if you like your variable names short).
This should work now. Just check against your code to see the changes.
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
得分: 1
在这一行中
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 数组的,而不是这种情况。
英文:
In the line
double[][] tests = new double[N][N];
of function arrangeList
you make your test array as N X N.
I believe youh should do something like
double[][] tests = new double[M][N];
It's just a suggestion as in your code it seems M = number of students and N = number of tests, differently from what you write in your question.
In general you should review all the method arrangeList
and probably getTestAvg
too (loop on N, instead of M), as the loops on variable len
are intended for a N X N array, which is not the case.
答案3
得分: 1
你需要考虑不同的大小。我认为你主要想要测试的数量(而不是学生),但你不能只是对两个索引边界都使用 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);
}
}
请注意,它不仅调整了数组的大小,还改变了循环条件,以便正确地循环内部和外部循环的次数。
英文:
You need to account for the different sizes. I think you want primarily the number of TESTS (not students), but you can't just use len
for both index bounds.
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);
}
}
Note that it didn't just resize the array, but it changed the loop conditions to loop the proper amount for inner and outer loop.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论