从文件中读取单词数,并计算唯一单词的数量



我应该从一个文件中读取,计算单词总数,然后计算唯一单词的数量,就像"ex"一样;我很快乐"有3个独特的单词。。。

我试着用HashMap来做这件事,但在运行时遇到了一个错误,我认为我不应该在这个例子中使用HashMap。有没有一种方法可以从文件中读取,并只使用array和ArrayList来计算唯一单词的数量?错误:线程"中出现异常;主";java.lang.NullPointerException

这是我使用哈希图的代码,但不起作用:

public static void main(String[]args)throws IOException{
Scanner in = new Scanner(new File ("Lincoln.txt"));
int totalWords = 0;


while( in.hasNext()){
String word = in.next();
String[] spaces = word.split(" ");
String[] comma = word.split(",");
totalWords++;
}
System.out.println("The number of words are " + totalWords);

Map<String,Integer> words = new HashMap<String,Integer>();
countWords("D:\Desktop\CPS\Lab11\Lincoln.txt",words);
in.close();
}
public static void countWords(String filename,Map<String,Integer>words)throws FileNotFoundException{
Scanner file = new Scanner(new File(filename));
while(file.hasNext()){
String word = file.next();
int count = words.get(word);

if(count != 0){
count++;
}
else{
count =1;
words.put(word,count);
}

}
file.close();
}

有没有一种方法可以从文件中读取,并只使用array和ArrayList来计算唯一字符的数量?

你的问题令人困惑。首先你谈论单词,然后你跳到字符。是哪一个?

如果我们回到80年代末,认为我们生活在一个只有ASCII字符的世界里,那么用数组计算唯一字符是可能的。

用数组或数组列表计算唯一的单词,或者在unicode世界中计算唯一的字符,……一点都不实用,实际上是不可能的(你当然可以做到这一点,但只能使用这些列表来实现糟糕的哈希图,或者写一个效率极低的算法来实现这一点(。

所以,让我们假设,事实上,你应该使用地图来实现这一点。

这段代码有很多代码风格的问题(比如你重复Lincoln.txt,一次是相对的,一次作为绝对路径(,你的"单词数量"计数器也被破坏了,因为你在空格(无用;scanner已经这样做了(和逗号(有用(上进行了拆分,但对这些拆分操作的结果却什么都不做。大概你想要totalWords += comma.length。或者完全去掉这个方面,把"一个词"定义为"用空格分隔的东西",忘记逗号。如果你不想忘记逗号,你应该更新扫描仪的分隔符,并告诉扫描仪单词是空格或逗号之间的东西(scanner.useDelimiter("[ ,]+")-这是正则表达式:分隔符是1或更多的任何序列[空格或逗号](。

但问题是这一行:

int count = words.get(word);

单词开始时为空,这意味着最初,words.get(word)向映射询问与尚未在映射中的键关联的值。在这种情况下,get方法返回null。然后,您将其分配给一个不能包含null的基元,因此java将通过对words.get(word)返回的内容调用.intValue()来"自动取消装箱"您的值。这会导致您观察到的NullPointerException,因为对空指针执行.foo可以做到这一点。你真正想要的是:;嘿,单词地图?请给我与键word关联的Integer对象,但如果你一开始没有映射,那么不要返回null,相反,你能返回0吗?谢谢&";。

这是可能的和容易的:

int count = words.getOrDefault(word, 0);

请注意,如果映射还不存在,则在映射中写入"1",但如果存在,则不执行任何操作(count++不会更改映射;java到处都是按值传递的。您从调用words.get(word)得到的count?它是一个副本。修改它对映射没有任何作用,您必须重新放置更新的值。

如果你想的话,你可以在一次合并中完成整个事情,但这可能会进入Lambda,这可能超出了你目前的水平。

最新更新