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

时间:2020-11-04 15:39:18

标签: java

我应该从文件中读取并计算单词总数,然后计算唯一单词的数量,例如对于前“我很高兴”有3个唯一单词...

我尝试使用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();
}

1 个答案:

答案 0 :(得分:0)

有没有一种方法可以读取文件并仅使用array和ArrayList计数唯一字符的数量?

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

如果我们回到80年代后期并认为我们生活在一个只有ASCII字符的世界中,就有可能用数组来计算唯一字符。

用数组或数组列表计数唯一单词,或在unicode世界中计数唯一字符……在丝毫,实际上不可能的情况下是不实际的(您当然可以做到这一点-但只能通过使用这些列表来手动笨拙地实现哈希图,或者编写一种效率极低的算法来做到这一点。

因此,我们仅假设您实际上打算为此使用地图。

此代码存在很多代码样式问题(例如,您重复Lincoln.txt,一次是相对的,一次是绝对路径),并且“单词数”计数器也被破坏了,因为您在空间(无用;扫描仪已经做到了)和逗号(有用)上进行了分割,但是对这些分割操作的结果却完全不执行任何操作。大概您想要totalWords += comma.length。或者只是完全摆脱该方面,将“一个单词”定义为“用空格隔开的东西”,而不必考虑逗号。如果您不想忘记逗号,则希望更新扫描仪的定界符,并告诉扫描仪单词是空格或逗号之间的东西(scanner.useDelimiter("[ ,]+")-的正则表达式是:定界符是任何序列1个或多个(空格或逗号)。

但是错误是这一行:

int count = words.get(word);

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

哪些是可能和容易的?

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

请注意,如果尚未在映射中写入“ 1”,则在映射中写入“ 1”,但如果不存在,则不执行任何操作(count++不会更改映射; java随处都按值传递。 count是通过调用words.get(word)获得的吗?它是副本。对其进行修改不会对该映射产生任何影响,您必须重新输入更新后的值。

如果您愿意,可以在一次合并中完成整个操作,但是这可能会超出您当前的水平。