Java分隔符跳过一个单词

时间:2012-06-03 00:45:01

标签: java unique java.util.scanner

我正在读取一个文本文件,并将该文本文件中的一组唯一单词存储到一个ArrayList中(如果有更好的结构,请建议这样做)。我正在使用扫描程序扫描文本文件并将分隔符指定为“”(空格),如下所示;

    ArrayList <String> allWords = new ArrayList <String> ();
    ArrayList <String> Vocabulary = new ArrayList <String> ();
    int count = 0;

    Scanner fileScanner = null;
    try {
        fileScanner = new Scanner (new File (textFile));

    } catch (FileNotFoundException e) {
        System.out.println (e.getMessage());
        System.exit(1);
    }

    fileScanner.useDelimiter(" ");

    while (fileScanner.hasNext()) {

        allWords.add(fileScanner.next().toLowerCase());

        count++;

        String distinctWord = (fileScanner.next().toLowerCase());
        System.out.println (distinctWord.toString());

        if (!allWords.contains(distinctWord)) {

            Vocabulary.add(distinctWord);

        }
    }

因此,在打印词汇表的内容后,每个单词后都会跳过一个单词。因此,例如,如果我有以下文本文件;

“快速的棕色狐狸跳过懒狗”

打印的内容是“快速狐狸懒”,然后它给我一个错误;

Exception in thread "main" java.util.NoSuchElementException
    at java.util.Scanner.throwFor(Unknown Source)
    at java.util.Scanner.next(Unknown Source)
    at *java filename*.getWords(NaiveBayesTxtClass.java:82)
    at *java filename*.main(NaiveBayesTxtClass.java:22)

有人可以就如何解决这个问题给我一些建议吗?我感觉它与fileScanner.useDelimiter和fileScanner.hasNext()语句有关。

2 个答案:

答案 0 :(得分:5)

在检查hasNext()一次后,你正在调用Scanner#next()两次,而你忽略了next()的一个返回。

你在(1)调用它并将其添加到allWords
并在(2)再次调用并打印出来。

while (fileScanner.hasNext()) {

    allWords.add(fileScanner.next().toLowerCase()); // **** (1)

    count++;

    String distinctWord = (fileScanner.next().toLowerCase());  // **** (2)
    System.out.println (distinctWord.toString());

    if (!allWords.contains(distinctWord)) {

        Vocabulary.add(distinctWord);

    }
}

解决方案:调用Scanner#next() 一次 ,保存返回给变量的String,然后将变量添加到HashSet,并打印变量。如,

while (fileScanner.hasNext()) {
    String word = fileScanner.next().toLowerCase();
    allWords.add(word); // **** (1)
    count++;
    // String distinctWord = (fileScanner.next().toLowerCase());  // **** (2)
    System.out.println (word);
    vocabularySet.add(word); // a HashSet
}

安全的一般规则是,对于Scanner#hasNextXXX()Scanner#nextXXX()的每次通话,您应该建立一对一的关系

答案 1 :(得分:2)

您还要求提供数据结构,您可以这样做:

    List<String> allWords = new ArrayList<String>();
    SortedSet<String> Vocabulary = new TreeSet<String>();
    int count = 0;

    Scanner fileScanner = null;
    try {
        fileScanner = new Scanner(new File(textFile));

    } catch (FileNotFoundException e) {
        System.out.println(e.getMessage());
        System.exit(1);
    }

    fileScanner.useDelimiter(" ");

    while (fileScanner.hasNext()) {
        String word = fileScanner.next().toLowerCase();
        allWords.add(word);
        if (Vocabulary.add(word)) {
            System.out.print("+ ");
        }
        System.out.println(word);
    }

正如您所看到的,变量由interface(List,SortedSet)声明并使用具体类实现。这不仅允许重新实现,而且对函数参数特别有用。