空文件字数 returns 1

Word count returns 1 for empty file

此代码用于计算输入中的字数。它有效,除非输入中没有单词 - 它 returns 1 而不是 0。这里有什么问题?

import java.util.Scanner;

public class Exercise12 {
    public static void main(String[] args) {
         Scanner kb = new Scanner(System.in);
         System.out.println("Input, Stop by #");
         String input = kb.nextLine();
         while (! input.equals("#")) {
             wordCount(input);
             input = kb.nextLine();             
            }
    } //main

    public static void wordCount(String countSpace) {
        int count = 1;
        for (int i =0; i < countSpace.length(); i++ ) {
            if ((countSpace.charAt(i)) == ' ') {
                count++;
            }
        }
        System.out.println(count);      
    }
} // class Exercise12

你可以像这样使用分割函数:

public static void wordCount(String countSpace) {

    String[] words = countSpace.split(" ");
    int count = words.length;

    System.out.println(count);  

}

编辑:

正如@Jérôme 在下面建议的那样,我添加了 trim 函数并检查了空输入,现在它可以正常工作了。正如@Aleks G 所建议的,我还将拆分函数中的字符串更改为“\s+”正则表达式。谢谢你的更正。请参阅下面的更新代码:

public static void wordCount(String countSpace) {

    String[] words = countSpace.trim().split("\s+");

    int count = 0;
    if (!(words[0].equals(""))){
        count = words.length;
    }        

    System.out.println(count); 
}

TL;DR: 使用 StringTokenizer:

public static void wordCount(String input) {
    int count = new java.util.StringTokenizer(input).countTokens();
    System.out.println(count);      
}

详细解释:

您的代码几乎是正确的,但是您将计数初始化为 1。然后为找到的每个 space 个字符递增它。在输入的末尾,你没有 space,因此你不会增加最后一个单词的计数 - 这会补偿你从 1 而不是 0 开始。但是,如果输入为空,你开始使用 1 并且没有任何内容可读 - 因此您最终得到了错误的值。

第一个修复很简单:将初始化更改为 int count = 0:

public static void wordCount(String countSpace) {
    int count = 0;
    for (int i =0; i < countSpace.length(); i++ ) {
        if ((countSpace.charAt(i)) == ' ') {
            count++;
        }
    }
    System.out.println(count);      
}

下一个问题是您计算的不是单词,而是单词分隔符。如果两个单词之间有两个连续的space怎么办?此外,如果遇到行尾或文件尾怎么办?你的代码会破坏这些。

理想情况下,您应该使用分词器来计算您的字数,但至少,您应该计算从 space/line-end 切换到字母数字字符的次数。下面是使用 Tokenizer 的示例:

public static void wordCount(String input) {
    int count = new java.util.StringTokenizer(input).countTokens();
    System.out.println(count);      
}

为了使一切正确,您应该 trim() 您的 String 删除前导和尾随空格。然后 split 空白处的 String 并计算所有非空的 String。空 String 是由连续的空格引起的。

使用Java8:

public static void wordCount(String countSpace) {
    System.out.println(Arrays.stream(countSpace.trim().split(" ")).filter(word->!word.isEmpty()).count());
}

您需要单独处理输入为空的情况。此外,您应该记住,输入可能包含两个连续的空格或行的 beginning/end 处的空格,这不应该算作单词。

对于这些特殊情况,代码将如下所示:

public static void wordCount(String in){
    boolean isspace = true;
    int count = 0;
    for(int i = 0; i < in.length(); i++)
    {
        //increment count on start of a word
        if(isspace && in.charAt(i) != ' ')
        {
            count++;
            isspace = false;
        }
        //reset isspace flag on end of a word
        else if(!isspace && in.charAt(i) == ' ')
            isspace = true;
    }

    System.out.println(count);
}

此代码确保仅在实际遇到单词时才计算单词数量,并忽略重复的空格。