我是一名编程第一年的学生,如果这是一个愚蠢的问题,请原谅我。
我尝试做的是阅读第1行包含答案密钥的文本文件,并且前面的行将包含学生的ID号及其对测试的答案。这是一个例子:
TFFTFFTTTTFFTFTFTFTT
ABC54301 TFTFTFTTTTF TFTFTFTT
ABC54302 TFFTFFFFFFFFTFTFTFTT
ABC54303 TFFTFFTTTTFFTFTTTTTT
ABC54304 TFFTTTFFTTFFTFTFTFTT
ABC54305 TFTFTFTTTTFFTFTFTFTT
我的想法是创建三个数组 - 一个只包含答案键,一个包含学生'身份证号码,以及包含学生答案的身份证号码。学生ID号始终为8位数,但可能包含空格。学生的答案总是20个字符,但也可以包含空格。所以我不能根据空格拆分它们。
说明中包含:
while (inFile.hasNext())
{
...
}
where 'inFile' is the Scanner object connected to the input file.
Each student's record should be read by two read's --
one string (for ID) and another string (answer string).
我很丢失。我最初的想法是循环遍历第一行的每一行,并将该行的每个段设置为其互补数组。我遇到的问题是,我似乎无法找到关于如何根据字符数分割线条的任何说明或说明。
我想的可能是:
while (inFile.hasNext())
{
// I would somehow set the first line to its own array
// As the loop continues, as long as its not the first line
idNums[i] = //Characters 1-8
studentAnswers[i] = //Characters 10-30
}
这合理吗?或者有更简单的方法吗?我觉得我以一种比必要更复杂的方式接近这一点。
编辑:
在详细了解了地图和正则表达式后,我尝试了几种不同版本的代码。第一个包括:
while (scan.hasNextLine()) {
String[] studentInfo = scan.nextLine().split(" ", 2);
info.put(studentInfo[0], studentInfo[1]);
}
哪种方式有效,但问题是如果以空格结束,则不会保存完整的20个字符。这是一个问题吗?我不确定。目前我正在测试这个:
String[] answerKey = scan.nextLine().split("");
Map<String, String[]> results = new HashMap<>();
while (scan.hasNextLine()) {
String line = scan.nextLine();
results.put(line.substring(0, 8), line.substring(9).split(""));
}
这给了我正确的键,但值不正确。值似乎指向内存位置。例如:
{ABC54339=[Ljava.lang.String;@55f96302
答案 0 :(得分:0)
首先在while循环之前读取第1行。您可以将其转换为如下数组:
String[] answers = inFile.nextLine().split("");
FYI,正则表达式告诉分裂在每个角色之间分开。
然后,为了阅读结果,您最好将学生ID和他们的答案保持在一起 - 地图是一个明显的选择,因为它存储键/值对,但也因为它自动增长。
使用substring获取该行的前8个字符并获取结果,并在地图中put()
。将结果值存储为数组,使用上面的相同拆分调用创建。
Map<String, String[]> results = new HashMap<>();
while ...
results.put(line.substring(0, 8), line.substring(9).split(""));
仅供参考,如果你正在使用java 8,你可以在一行中完成(即没有循环),虽然它有点像火车残骸:
Map<String, String[]> results = StreamSupport
.stream(Spliterators.spliteratorUnknownSize(inFile, 0))
.collect(Collectors.toMap(s -> s.substring(0, 8), s -> s.substring(9).split(""));
顺便说一句,如果你的老师给你初始代码供你填写,它清楚地表明他或她的软件设计能力差;扫描仪变量不应该包含&#34; file&#34;在其中,因为它在输入流上运行,而不仅仅是文件输入流 - 例如,您的代码可以通过命令行的输入运行。代码不应该知道,关心或建议输入的特定来源:scanner
或简单地in
将是更好的选择。
答案 1 :(得分:0)
由于您的说明明确表示您应该进行2次阅读,因此在阅读This Documentation后我发现的最佳方式是Scanner.Next(string)
它看起来像&#34;模式&#34;参数需要一个正则表达式,http://rubular.com/是用于试验正则表达式的很好的资源,它还有一个基本正则表达式语法的参考。
为方便起见,匹配8个字符的正则表达式为".{8}"
如果您使用正则表达式,请确保您转义用于正则表达式转义序列的所有\
(对于java的转义和正则表达式语言的转义),以匹配数字,你必须使用"\\d"
答案 2 :(得分:0)
将第一行读入字符串并将其保留为字符串(字符串是一个字符数组)。读取剩余的行并使用学生的ID作为键将它们存储在Map中(使用line.substring(0,line.indexOf(“”))和行的其余部分(字符串)作为Map的值(行) .substring(line.indexOf(“”)+ 1)。+ 1是跳过空格。
现在,您可以浏览地图并将每个学生的(字符串)答案与答案密钥进行比较
for (int i = 0; i < answer.Length; i++)
{
// Make sure you don't step out of bounds of the array for student's answer
// Any answers not checked will be considered wrong
if (i < studentsAnswer.Length)
{
if (studentsAnswer.charAt(i) != answer.charAt(1))
{
numberOfIncorrect = numberOfIncorrect + 1;
}
}
else
{
numberOfIncorrect = numberOfIncorrect + 1;
}
}
希望这会有所帮助......