2015-03-31 3 views
0

Я студент-программист на первом курсе, так что простите меня, если это глупый вопрос.Как создать несколько массивов из одной текстовой строки?

То, что я пытаюсь сделать, это прочитать текстовый файл, содержащий ключ ответа в строке 1, а исходящие строки будут содержать идентификационный номер студента и их ответы на тест. Вот пример:

TFFTFFTTTTFFTFTFTFTT 
ABC54301 TFTFTFTTTTF TFTFTFTT 
ABC54302 TFFTFFFFFFFFTFTFTFTT 
ABC54303 TFFTFFTTTTFFTFTTTTTT 
ABC54304 TFFTTTFFTTFFTFTFTFTT 
ABC54305 TFTFTFTTTTFFTFTFTFTT 

Моя идея заключается в том, чтобы создать три массива - тот, который содержит только ключ ответа, один, содержащий идентификационные номера учащихся, а тот, который содержит studentss ответы. Идентификатор студента всегда 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 
} 

ли что разумно? Или есть более простой способ? Я чувствую, что приближаюсь к этому более сложным образом, чем это необходимо.

EDIT:

После получения дополнительной информации о картах и ​​регулярных выражениях, я попытался несколько различных версий этого кода. Первый состоял из:

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

Сначала прочитайте строку 1 перед циклом while. Вы можете превратить это в массив, как это:

String[] answers = inFile.nextLine().split(""); 

FYI, что регулярное выражение рассказывает расколоть, чтобы разделить между каждым символом.

Затем, чтобы прочитать результаты, вам лучше сохранить идентификатор студента и их ответы вместе - карта является очевидным выбором, поскольку она хранит пары ключ/значение, а также потому, что она растет автоматически.

Используйте подстроку, чтобы получить первые 8 символов линии, а также получить результаты, и put() их на карте. Сохраните значение результата в виде массива, созданного с использованием того же разделенного вызова выше.

Map<String, String[]> results = new HashMap<>(); 
while ... 
    results.put(line.substring(0, 8), line.substring(9).split("")); 

FYI, если вы используете 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("")); 

As в стороне, если ваш учитель дал вам исходный код для заполнения, он ясно показывает, что у него плохое умение создавать дизайн программного обеспечения; переменная сканера не должна содержать в ней слова «файл», поскольку она работает с входным потоком, а не только с входным потоком файла, например, ваш код может работать через ввод из командной строки. Код не должен знать, заботиться или предлагать конкретный источник ввода: scanner или просто in - лучший выбор.

+0

Спасибо Я не узнал о картах еще - но услышав, что от нескольких пользователей здесь, то это будет, как я подойти к этой проблеме вы не возражаете, обеспечивая маленький кусочек. скелетного кода или псевдокода дать пример того, как карта будет работать в этом случае? Я использую Java 8. – ccsum

+0

Я думаю, что делаю простую ошибку, но я не вижу, что это такое. Я изучал карты и регулярное выражение в течение последних двух часов - возможно, я слишком долго смотрел на это, или, может быть, я просто делаю что-то неправильно. Обновит исходное сообщение новым кодом. Я попробовал это в комментариях, и это не сработает - упс! – ccsum

+0

с java 8 вы можете просто использовать пустое регулярное выражение '' '' для разделения каждого символа - пока еще не изучайте регулярное выражение (оно будет жарить ваш мозг). Игнорируйте код java 8 - это было просто интересно. Попробуйте простой цикл - он должен работать. После того, как цикл напечатает карту, проверьте, не работает ли она. Затем вы можете выполнить итерацию по карте, итерации по 'map.entrySet()' – Bohemian

0

Поскольку ваши инструкции явно говорят, что вы должны сделать 2 гласит, лучший способ я нашел после прочтения This Documentation для выполнения этих инструкций с Scanner.Next(string)

Это выглядит как параметр «образец» ожидает, что регулярное выражение, http://rubular.com/ - отличный ресурс для экспериментов с регулярными выражениями, а также ссылка на базовый синтаксис regex.

Для вашего удобства, регулярное выражение для сопоставления 8 символов это ".{8}"

Если вы используете регулярные выражения, убедитесь, что вы избежать всех ваших \ S, которые вы используете для последовательности регулярных выражений побега (на побег java и 1 для языка регулярных выражений), поэтому, чтобы соответствовать числовой цифре, вы должны использовать "\\d"

+0

Спасибо за ссылку на документацию и ссылку! Я обязательно изучу эти ресурсы. Мы еще не узнали о регулярном выражении, поэтому я буду учиться, пока я решу эту проблему. Содержание раздела для этой проблемы касалось массивов. – ccsum

+0

После нескольких часов экспериментов я не могу заставить регулярное выражение работать правильно. Мне нужно, чтобы он остановился только после определенного количества символов, но разделитель, который вы рекомендовали («. {8}»), похоже, не работает.Пространства работают, но мне нужно сохранить пробелы. Я сейчас в тупике, но я буду продолжать работать над этим. – ccsum

0

Прочитайте первую строку в строке и оставьте ее в виде строки (строка представляет собой массив символов). Прочитайте оставшиеся строки и сохраните их на Карте, используя идентификатор ученика в качестве ключа (используйте строку .substring (0, line.indexOf ("")), а остальную часть строки (строки) в качестве значения для карты (строка .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; 
    } 
} 

Надеется, что это помогает ...

+0

Спасибо! Я не знаю, что такое Карты, но даже правильная терминология для исследований помогает мне. – ccsum

+0

Я отредактировал свое оригинальное сообщение. Идея сохранения первой строки в строке отлично работала - но я в тупике, пытаясь правильно получить ключи/значения в Карте. Возможно, я просто зациклен на синтаксисе? – ccsum

+0

Второй параметр вашей карты не обязательно должен быть строковым массивом, просто сделайте его строкой (Map ). Затем, когда вы кладете ключ/значение на свою карту, вам не нужно разделить значение (results.put (line.substring (0, 8), line.substring (9)). После того, как у вас есть все это, просто пройдите все пары ключ/значение на вашей карте, и вы можете использовать мой фрагмент в моем ответе, чтобы проверить результаты. – Shar1er80