簡體   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