2017-01-10 5 views
0

Я практикую Java самостоятельно из книги. Я прочитал главу о классах обработки текста и обертки и попытался выполнить упражнение ниже.Java - Как разделить отдельные кавычки вокруг фразы, но не апострофа в Word

Слово Счетчик

Напишите программу, которая запрашивает у пользователя имя файла. Программа должна отображать количество слов, содержащихся в файле.

import java.io.File; 
import java.io.IOException; 
import java.util.Scanner; 
import java.util.StringTokenizer; 

public class FileWordCounter { 

    public static void main(String[] args) throws IOException { 

     // Create a Scanner object 
     Scanner keyboard = new Scanner(System.in); 

     // Ask user for filename 
     System.out.print("Enter the name of a file: "); 
     String filename = keyboard.nextLine(); 

     // Open file for reading 
     File file = new File(filename); 
     Scanner inputFile = new Scanner(file); 

     int words = 0; 
     String word = ""; 

     while (inputFile.hasNextLine()) { 
      String line = inputFile.nextLine(); 
      System.out.println(line); // for debugging 
      StringTokenizer stringTokenizer = new StringTokenizer(line, " \n.!?;,()"); // Create a StringTokenizer object and use the current line contents and delimiters as parameters 
      while (stringTokenizer.hasMoreTokens()) { // for each line do this 
       word = stringTokenizer.nextToken(); 
       System.out.println(word); // for debugging 
       words++; 
      } 
      System.out.println("Line contains " + words + " words"); 
     } 

     // Close file 
     inputFile.close(); 

     System.out.println("The file has " + words + " words."); 
    } 

} 

Я выбрал это случайное стихотворение из Интернета, чтобы проверить эту программу. Я положил стихотворение в файл с именем TheSniper.txt:

Two hundred yards away he saw his head; 
He raised his rifle, took quick aim and shot him. 
Two hundred yards away the man dropped dead; 
With bright exulting eye he turned and said, 
'By Jove, I got him!' 
And he was jubilant; had he not won 
The meed of praise his comrades haste to pay? 
He smiled; he could not see what he had done; 
The dead man lay two hundred yards away. 
He could not see the dead, reproachful eyes, 
The youthful face which Death had not defiled 
But had transfigured when he claimed his prize. 
Had he seen this perhaps he had not smiled. 
He could not see the woman as she wept 
To the news two hundred miles away, 
Or through his very dream she would have crept. 
And into all his thoughts by night and day. 
Two hundred yards away, and, bending o'er 
A body in a trench, rough men proclaim 
Sadly, that Fritz, the merry is no more. 
(Or shall we call him Jack? It's all the same.) 

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

Enter the name of a file: TheSniper.txt 
Two hundred yards away he saw his head; 
Two 
hundred 
yards 
away 
he 
saw 
his 
head 
Line contains 8 words 
He raised his rifle, took quick aim and shot him. 
He 
raised 
his 
rifle 
took 
quick 
aim 
and 
shot 
him 
Line contains 18 words 
... 

В конце моя программа показывает, что стихотворение содержит 176 слов. Однако Microsoft Word насчитывает 174 слова. Я вижу, что печатаю каждое слово, что я извиняю апострофы и одинарные кавычки. Вот последняя часть стихотворения в моем выходе, где возникает проблема:

(Or shall we call him Jack? It's all the same.) 
Or 
shall 
we 
call 
him 
Jack 
It 
s 
all 
the 
same 
Line contains 176 words 
The file has 176 words 

В моем списке параметров StringTokenizer, когда я не разграничивают апостроф, который выглядит как апостроф, слово «Это» считается одним. Однако, когда я это делаю, он считается двумя словами (It and s), потому что апостроф, который похож на одну цитату, делится. Кроме того, фраза «К юбилею, я получил его!» когда я не ограничиваю единую цитату/апостроф. Являются ли апостроф и одинарная кавычка одинаковым персонажем, когда дело доходит до их разграничения? Я не уверен, как разграничить одинарные кавычки, которые окружают фразу, но не апостроф между словом типа «Это». Надеюсь, я несколько ясно задаю свой вопрос. Просьба уточнить. Любые рекомендации приветствуются. Спасибо!

+1

Есть ли причина, почему вы не можете просто использовать пробелы (пробел, табуляция, newline) в качестве разделителей? В фразе «По Юпитеру, я получил его!», Не имеет значения, является ли первое слово «By», а последнее - «его!» Для целей _counting_ слов, хотя оно не выглядит как приятно при печати, какие слова были найдены (что только для отладки, за ваш комментарий). (также см. http://stackoverflow.com/questions/8813779/) –

+0

Спасибо! В этом есть смысл. – camelCoder

ответ

1

Почему бы не использовать другой сканер для каждой строки, чтобы подсчитать количество слов?

int words = 0; 
    while (inputFile.hasNextLine()) { 
     int lineLength = 0; 
     Scanner lineScanner = new Scanner(inputFile.nextLine()); 
     while (lineScanner.hasNext()) { 
      System.out.println(lineScanner.next()); 
      lineLength++; 
     } 
     System.out.println("Line contains " + lineLength + " words"); 
     words += lineLength; 
    } 

Я не считаю, что можно разграничить апостроф для фразы, как «'By Jove, я получил его!», Но игнорировать его в «это», если вы не используете поиск регулярных выражений для игнорировать одинарные кавычки в середине слова.

В качестве альтернативы вы можете рассматривать символы «.!?;,()» Как часть одного слова (например, «Джек?» - это одно слово), которое даст вам правильное количество слов. Это то, что делает сканер. Просто измените разделитель в вашем StringTokenizer к «» (\ п не требуется, так как вы уже ищете каждую строку):

StringTokenizer stringTokenizer = new StringTokenizer(line, " "); 
Смежные вопросы