如何从一个文本行创建多个数组?

时间:2015-03-31 19:17:39

标签: java arrays input multidimensional-array while-loop

我是一名编程第一年的学生,如果这是一个愚蠢的问题,请原谅我。

我尝试做的是阅读第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

3 个答案:

答案 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;
    }
}

希望这会有所帮助......