这个问题不适合胆小的人,而且耗费时间。
我正在学习Java,我想知道是否有人可以通过我的程序告诉我我做错了什么以及如何修复它以便我可以学习。
我的整个程序(如果需要):http://pastie.org/private/xpbgpypetvfmivcs88gbcq
分配:
不允许使用全局变量! 你被要求写一个程序 对真假的结果进行评分 测验并显示结果 表格形式。测验由10个组成 的问题。这个数据文件 问题包括1套正确 第一行的答案(答案) 后续的行包含四个 数字学生识别号码 然后是那个学生的10 响应。 (学生人数 参加目前未知的测验。)
数据文件的格式为:
TFFTFTTFTT
0461 TTFTTFTFTT
3218 TFFTTTTTFT
.....................
....................
你的程序应该读取密钥和 将其存储在一维数组中。 然后它应该读取并处理每个 后续行,存储学生 识别号码一个 维数组和等级 两个独立的一维阵列 - 一个用于数字等级和用于 字母成绩。
数字成绩转换为字母 根据以下系统: A(10),B(9),C(8-7),D(6-5),F(4-0)。
程序输出应包括 以下:
每位学生的四位数识别号码,即数字 等级及其字母等级。
打印了多少名学生参加测验。
整个班级的数字测验平均值。
- 醇>
A,B,C,D和F的频率计数 全班。
编辑:
哦,嘿。对不起,我仍然知道如何做到这一切:(好吧,这里有。
程序没有编译,我很确定这取决于我的逻辑。 (以及一些句法的东西)。
我遇到的问题: 1)如何将所有参数传递给每个不同的方法,如此处所示。我想要做的是让我返回的所有值,例如answerKey,studentAnswers,numericGrade,average等,这样我就可以使用它们并打印出来。但我不知道该怎么做。
int[] numericGrade = computeNumericGrade(answerKey, studentAnswers);
int[] letterGrade = computeLetterGrade(numericGrade);
double average = average(numericGrade);
int gradeTally = gradeTally(letterGrade);
int studentCount = studentCount(numericGrade);
2)我无法弄清楚如何单独检查每个T或F值,并检查它是否与答案键中的T或F相对应,如下所示。
我要做的是检查特定元素的每个字母,如果值为“correct”或== answerKey,则在该元素的numericGrade中添加总数。
public static int[] computeNumericGrade(int[] answerKey, int[] studentAnswers) {
int[] numericGrade = new int[50];
int total = 0;
for(int i = 0; i < 50;i++) {
for(int a = 0;a == 10;a++) {
total = studentAnswers[i].charAt(a);
if(total == answerKey[i]) numericGrade[i]++;
}
}
return numericGrade;
}
3)我不知道如何返回所有这些不同的值,因为我需要它们以上!我希望这组代码检查每个元素的字母等级,如果找到这个元素,++是与之对应的变量,所以我知道有多少这个字母被称为。
public static int gradeTally(String[] letterGrade) {
int a, b, c, d, f = 0;
for(int i = 0;i < letterGrade.length;i++) {
if(letterGrade[i] == 'A') a++;
else if (letterGrade[i] == 'B') b++;
else if (letterGrade[i] == 'C') c++;
else if (letterGrade[i] == 'D') d++;
else if (letterGrade[i] == 'F') f++;
}
return a + b + c + d + f;
}
4)我无法弄明白......我想我很亲近。在这里,我正在尝试读取文件,对其进行标记,然后对于每个标记,将其添加到数组1中。但是,我不认为这是正确的,但我无法检查,因为我可以不能编译......
public static String[] getData() throws IOException {
int[] studentID = new int[50];
String[] studentAnswers = new String[50];
int total = 0;
String line = reader.readLine();
strTkn = new StringTokenizer(line);
String answerKey = strTkn.nextToken();
while(line != null) {
studentID[total] = Integer.parseInt(strTkn.nextToken());
studentAnswers[total] = strTkn.nextToken();
total++;
}
return studentAnswers;
}
我现在正在编辑我的帖子。我希望这足够了:))
答案 0 :(得分:4)
我猜你从评论中意识到这有点难以帮助。
我不确定它会有多大帮助,但我想提供一些关于如何处理这个问题的一般提示。
首先,我可能会扔掉你所拥有的并重新开始。我从不遗憾地丢弃代码 - 从长远来看,它总能帮助你的代码,第二次你会学到很多东西。
其次,从小做起。做一些有用的东西 - 即使它只是读入值并证明它们被正确读入,然后展开它。经常测试。每当您添加代码时,请在测试中添加一行以确保新代码的工作方式与之前的所有代码一致
这样一来,如果有什么破坏,你就会确切地知道是什么打破了它 - 你编辑的最后一件事。
要进行这种快速测试,您应该学习使用JUnit进行单元测试,或者让主要测试用于测试,这样您就可以点击一个按钮立即得到答案。 (JUnit真的不难,它内置于Eclipse中。哦,是的,下一个提示)。
使用ECLIPSE或NetBeans!
这些都是经验丰富的程序员自动知道和做的事情。从长远来看,在开始时投入一点时间和精力可以节省很多痛苦。
答案 1 :(得分:3)
由于您仍然坚持编译,我将尝试帮助您在解决代码中的逻辑之前克服那个绊脚石。
有些规则会导致代码无法编译,包括语法规则,但这些规则通常不被称为“逻辑”。我会在程序运行时描述逻辑错误,但不会按照您的意愿执行。安美居...
许多编译器错误的形式如下:
someField cannot be resolved
当您尝试引用编译器在该点无法“看到”的变量时,会发生这种情况。在你的情况下,这是因为当你想要引用变量时,你已经将变量声明在无法看到它们的地方。
main()
方法中的几个字段就是这种情况。这归结为范围的问题。为了能够引用变量,例如answerKey
或studentAnswers
,它们必须在范围内。全局范围是指您可以从任何地方引用变量,这是您要避免的。您已在方法中声明变量answerKey
,studentAnswers
,如下所示:
public static String[] getData() throws IOException {
// other code
String[] studentAnswers = new String[50];
// other code
String answerKey = strTkn.nextToken();
// other code
}
您对这些声明所做的工作是studentAnswers
和answerKey
“在getData()
方法的范围内”。这意味着它们不能在别处引用,并且是main()
中编译器错误的原因。
这样做的一种方法是全局声明变量 - 例如public static String answerKey;
下的public class GradeResults {
,但是你被要求特别不要这样做(并且有充分的理由,我赢了'进入)。
我建议的另一种方法是“封装”变量。这是一个奇特的编程词,大致意味着将数据和行为包装到一个对象中,让对象决定如何表现和改变自己。我会给你一种你可以开始使用它的方法(有许多方法可以做到)。那就是使用一个名为Student
的新类,将我们可以创建的有关学生的所有信息封装在一起。
// this is a new class, and will have to be saved in a file called Student.java
public class Student {
// these are field declarations
private int id;
private String answers;
// this is the constructor, it creates a new instance of Student
public Student(int newStudentsId, String newStudentsAnswers) {
// these lines take the parameters (in brackets on the line above)
// and assign them to the fields of this instance
this.id = newStudentsId;
this.answers = newStudentsAnswers;
}
// after this you could have getters for the fields,
// these are often referred to as "accessors" in introductory texts
// this is all I'll give you of this example, to get you started
} // End of class Student.java
您看到的其余编译器错误稍微容易一些:
Incompatible operand types String and char
在代码中:
public static int gradeTally(String[] letterGrade) {
// other code
if(letterGrade[i] == 'A') a++; // error on this line
letterGrade[i]
引用的变量类型是String,常量'A'
是char。修复此
'A'
更改为"A"
,注意双引号而不是单引号,单引号适用于char
类型,double适用于String
类型。其他选择是:letterGrade
数组的类型更改为声明它的char[] letterGrade
(在方法签名的参数列表中)。这与导致编译器错误的问题大致相同:
Cannot invoke charAt(int) on the primitive type int
使用代码:
total = studentAnswers[i].charAt(a);
charAt
是String
类的一种方法,因此studentAnswers[i]
必须引用String
类型的变量。但它被声明为int[] studentAnswers
,因此存在“类型不匹配”。
这里有很多想法,我留下了很多空白,你必须自己填写。关于使用Java的面向对象编程的一个很好的介绍性文本(例如Objects First With Java)应该涵盖你需要的一切。
答案 2 :(得分:0)
我已经快速浏览了第2)点和第3点:
2)我认为这里的目的是通过检查studentAnswers
数组中哪些元素与answerKey
中的元素相等来确定正确答案的数量。假设这是目标,那么我的提示将是:
java.lang.String
类的方法,但您根本没有使用String
。 3)您应该考虑返回一个能够存储等级记录的不同对象。例如,您可以考虑Map<Character, Integer>
,其中地图的键是等级,值是等级频率。
答案 3 :(得分:0)
Java是一种面向对象的语言。从对象的角度思考。这只是用Java编写的C或Fortran。我无法看到封装或信息隐藏。
这可能是因为它是第一个编程课程,而你的教授可能不理解对象。但那就是你应该与Java合作的地方。
我希望看到学生,班级,年级(可能是枚举)等课程,ReportCard。相反,我所看到的只是原始人。总有一天你会把这看作是如何写Java的一个例子。