我应该写一个程序来读取一个叫做mobydick.txt的文件。这个文件包含了《白鲸》这本书的全部内容。mobydick.txt文件如下所示
我必须读取文件,显示文件中的每个唯一单词,然后显示每个唯一单词的出现次数。
输出应如下所示:
字数
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");
}
}
}
然而,当我运行这段代码时,我得到了一个奇怪的输出。
这很奇怪,因为如果我为这样一个更小更简单的文本文件运行相同的代码,那么输出看起来就像我想要的那样。
mobydick.txt有什么问题吗?
1条答案
按热度按时间kxe2p93d1#
只需查看文本输入文件。例如,它包含,
ago-never
. 程序员使用的计算机工具往往非常愚蠢,因为美国程序员需要它们非常简单。扫描器按空格分割。句号。-
不是空白。扫描仪尽职尽责地给你ago-never
作为一个标记。如果书中有Cosmic said: "Sheesh, this coding stuff is hard, man!".
,然后这些是scanner将提供给您的令牌:这显然不是你想要的。你想举个例子
man
. 不是man!".
.第二个问题是文本文件是文件,因此是bag-o-bytes。字节不是字符。所以,当你把你的文件变成一个扫描器时,你隐含地要求计算机对如何做到这一点大刀阔斧:它将使用“平台默认编码”,也就是javaese,意思是“永远不要你想要的”。这里没有简单的答案。有人需要调查或者告诉你编码是什么。可能是utf-8。在这种情况下,你必须告诉java:
你没有这样做,所以java选择了“平台默认编码”,这是一种任意的、通常是错误的选择,因此类似于“ha”ägen dasz的错误-只有最基本的字符在错误的字符集编码下才能在转换中存活。
至于如何解决第一个问题,可能您真正需要的只是告诉scanner您希望“令牌之间的东西”是“任意数量的非字母”。定界符是一个regexp,它大概是一个你还没学过的概念;这很复杂。正则表达式
\W+
表示“1个或多个‘非单词’字符”的概念,作为分隔符意味着感叹号、引号、圆点、换行符的序列-都会作为分隔标记的事物而消失。-也不是一封信,所以,ago-never
在输入文件中,将给您两个标记:ago和never。您仍然应该将输入小写,扫描仪无法为您执行此操作。
要设置分隔符:
编辑:使用此答案
[^a-zA-Z]+
但正如@vgr在评论中指出的,\\W+
更容易理解;一般来说,它可能更为地道。