繁体   English   中英

(Java)试图读取一个txt文件并计算每个单词的出现次数

[英](Java) Trying to read a txt file and count the number of occurrences for each word

我应该编写一个程序来读取名为 mobydick.txt 的文件。 该文件包含《白鲸记》这本书的全文。 mobydick.txt 文件看起来像这样

我必须读取文件,显示文件中的每个唯一单词,然后显示每个唯一单词的出现次数。

output 应如下所示:

字号

43

鲸鱼 12

船 93

到目前为止,这是我的代码:

import java.util.*;
import java.io.*;
public class Main
{
    public static void main(String[] args) throws IOException
    {
        //Create input stream & scanner
        FileInputStream fin = new FileInputStream("mobydick.txt");
        Scanner fileInput = new Scanner(fin);
        
        //Create Arraylist
        ArrayList<String> words = new ArrayList<String>();
        ArrayList<Integer> count = new ArrayList<Integer>();
        
        //Read through file and find the words
        while(fileInput.hasNext()) 
        {
            //Get next word
            String nextWord = fileInput.next();
            //Determine if the word is in the arraylist
            if(words.contains(nextWord))
            {
                int index = words.indexOf(nextWord);
                count.set(index, count.get(index) + 1);
            }
            else
            {
                words.add(nextWord);
                count.add(1);
            }
            
        }
        //close
        fileInput.close();
        fin.close();
        System.out.println("WORDS COUNT");
        //Print out the results
        for(int i = 0; i < words.size(); i++)
        {
            System.out.print(words.get(i) + "      " + count.get(i) + "\n");
        }
       
    }
}

然而,当我运行这段代码时,我得到了一个奇怪的output

这很奇怪,因为如果我为这样一个更小更简单的文本文件运行相同的代码,output 看起来就像我想要的一样

我在 mobydick.txt 上做错了什么?

只需查看文本输入文件。 例如,它包含ago-never 程序员的计算机工具往往非常愚蠢,因为我们程序员需要它们非常简单。 扫描仪在空白处拆分。 时期。 -不是空格。 Scanner 尽职尽责地为您提供ago-never作为单一令牌。 如果书中包含Cosmic said: "Sheesh, this coding stuff is hard, man.". ,那么这些是扫描仪将为您提供的令牌:

Cosmic
said:
"Sheesh,
this
coding
stuff
is
hard,
man!".

这显然不是你想要的。 你想要例如man 不是man.".

第二个问题是文本文件是文件,因此是bag-o-bytes。 字节不是字符。 所以,当你把你的文件变成扫描仪时,你隐含地要求计算机对如何做到这一点进行猛烈抨击,而且它会:它将使用“平台默认编码”,这是 java-ese 用于'从来没有你想要的'。 这里没有简单的答案。 有人需要调查或告诉你编码是什么。 可能是 UTF-8。 在这种情况下,你必须告诉 java:

new Scanner(fin, "UTF-8")

你没有,所以 java 选择了“平台默认编码”,这是一些随意且通常错误的选择,因此像“Haägen Dasz”这样的东西会搞砸 - 只有最基本的字符往往会在使用错误字符集编码的转换中幸存下来。

至于如何解决第一个问题,您可能真正需要的只是告诉扫描仪您希望“令牌之间的东西”是“任意数量的非字母”。 定界符是一个正则表达式,它可能是一个你还没有学过的概念; 这很复杂。 正则表达式\W+表示:“1 个或多个'非单词'字符”的概念,并且作为分隔符意味着感叹号、引号、点、换行符的序列 - 都作为分隔标记的事物而消失。 - 也不是字母,因此,输入文件中的ago-never将给您两个标记:ago 和 never。

您仍然应该将输入小写,扫描仪无法为您执行此操作。

要设置分隔符:

scanner.useDelimiter("\\W+"); // double backslash. That's not a typo.

编辑:这个答案以前使用过[^a-zA-Z]+ ,但正如@VGR 在评论中指出的那样, \\W+更容易理解; 一般来说,它可能更惯用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM