[英]Read in number of words from file and count amount of unique words
我应该从文件中读入并计算总字数,然后计算唯一字数,例如“我很高兴”有 3 个唯一字...
我尝试使用 HashMap 执行此操作,但是在运行时出现错误,并且我认为我不应该在此示例中使用哈希图。 有没有办法从文件中读取并仅使用数组和 ArrayList 来计算唯一单词的数量? 错误:线程“main”中的异常 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();
}
有没有办法从文件中读取并仅使用数组和 ArrayList 来计算唯一字符的数量?
你的问题令人困惑。 首先你谈论单词,然后你跳到字符。 哪一个?
如果我们回到 80 年代后期并认为我们生活在一个只存在 ASCII 字符的世界中,那么用数组计算唯一字符是可能的。
使用数组或数组列表计算唯一单词,或计算 unicode 世界中的唯一字符……一点也不实用,实际上是不可能的(你当然可以做到——但只能通过使用这些列表来处理蹩脚的实现哈希映射或编写一个极其低效的算法来做到这一点)。
因此,让我们假设您实际上打算为此使用地图。
此代码存在一堆代码样式问题(例如您重复 Lincoln.txt,一次是相对路径,一次是绝对路径),并且您的“字数”计数器也已损坏,因为您拆分了空格(没用;扫描仪已经这样做了)和逗号(有用),但是对这些拆分操作的结果完全不做任何事情。 大概你想要totalWords += comma.length
也许。 或者只是完全摆脱那个方面,并将“单词”定义为“由空格分隔的内容”,而忘记逗号。 如果您不想忘记逗号,您需要更新扫描仪的分隔符并告诉扫描仪单词是空格或逗号之间的东西( scanner.useDelimiter("[ ,]+")
- 那是正则表达式: 分隔符是 1 个或多个 [空格或逗号] 的任何序列)。
但错误是这一行:
int count = words.get(word);
words 一开始是空的,这意味着最初, words.get(word)
正在向地图询问与地图中尚未存在的键相关联的值。 在这种情况下,get 方法返回null
。 然后您将它分配给一个不能保存空值的原语,因此 java 将通过在words.get(word)
返回的事物上调用.intValue()
来“自动拆箱”您的值。 这会导致您观察到的NullPointerException
,因为对空指针执行.foo
就是这样做的。 你真正想要的是:“嘿,映射的话,请给我与该键关联的Integer对象? word
,但如果你不首先有一个映射这一点,那么不返回null,相反,你可以返回0?谢谢!”。
这是可能的和容易的:
int count = words.getOrDefault(word, 0);
请注意,如果地图尚不存在,则在地图中写入“1”,但如果存在,则不执行任何操作( count++
不会更改地图;java 到处都是按值传递。您从调用words.get(word)
获得的count
words.get(word)
? 它是一个副本。修改它对该地图没有任何影响,您必须重新放置更新后的值。
如果您愿意,您可以在一次合并中完成整个事情,但这可能会超出您当前的水平。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.