计算java中.txt文件中单词的频率

时间:2015-04-08 22:46:55

标签: java loops hashmap try-catch

我正在进行Comp Sci任务。最后,程序将确定文件是用英语还是法语写的。现在,我正在努力解决计算.txt文件中出现的单词频率的方法。

我在英文和法文中都有一组标有1-20的文件夹。该方法要求一个目录(在这种情况下是" docs / train / eng /"或者#34; docs / train / fre /")以及该程序有多少个文件应该通过(每个文件夹中有20个文件)。然后它读取该文件,将所有单词分开(我不需要担心大小写或标点符号),并将每个单词放在HashMap中以及它们在文件中的次数。 (键=字,值=频率)。

这是我为该方法提出的代码:

public static HashMap<String, Integer> countWords(String directory, int nFiles) {
// Declare the HashMap
HashMap<String, Integer> wordCount = new HashMap();

// this large 'for' loop will go through each file in the specified directory.
for (int k = 1; k < nFiles; k++) {
  // Puts together the string that the FileReader will refer to.
  String learn = directory + k + ".txt";

try {
  FileReader reader = new FileReader(learn);
  BufferedReader br = new BufferedReader(reader);
  // The BufferedReader reads the lines

  String line = br.readLine();


  // Split the line into a String array to loop through
  String[] words = line.split(" ");
  int freq = 0;

  // for loop goes through every word
  for (int i = 0; i < words.length; i++) {
    // Case if the HashMap already contains the key.
    // If so, just increments the value

    if (wordCount.containsKey(words[i])) {         
      wordCount.put(words[i], freq++);
    }
    // Otherwise, puts the word into the HashMap
    else {
      wordCount.put(words[i], freq++);
    }
  }
  // Catching the file not found error
  // and any other errors
}
catch (FileNotFoundException fnfe) {
  System.err.println("File not found.");
}
catch (Exception e) {
  System.err.print(e);
   }
 }
return wordCount;
}

代码编译。不幸的是,当我要求它打印20个文件的所有字数的结果时it printed this。它是完全的胡言乱语(尽管这些词语肯定存在)并且根本不是我需要的方法。

如果有人可以帮我调试我的代码,我将非常感激。我已经多年了,经过测试后进行测试,我已经准备放弃了。

3 个答案:

答案 0 :(得分:3)

我本来期待更像这样的事情。它有意义吗?

if (wordCount.containsKey(words[i])) { 
  int n = wordCount.get(words[i]);    
  wordCount.put(words[i], ++n);
}
// Otherwise, puts the word into the HashMap
else {
  wordCount.put(words[i], 1);
}

如果单词已经在hashmap中,我们想要获取当前计数,添加1并将该单词替换为hashmap中的新计数。

如果这个单词还没有出现在hashmap中,我们只需将它放在地图中,计数为1即可。下次我们看到相同的单词时,我们会将计数增加到2等等。

答案 1 :(得分:2)

如果仅按空格分割,则其他符号(括号,标点符号等)将包含在单词中。例如:"This phrase, contains... funny stuff",如果您按空格分割,则会得到:"This" "phrase," "contains..." "funny""stuff"

您可以通过按字边界(\b)拆分来避免这种情况。

line.split("\\b");

顺便说一下你的if和else部分是否相同。你总是将freq增加一,这没有多大意义。如果单词已经在地图中,您希望获得当前频率,为其添加1,并更新地图中的频率。如果没有,则将其放在地图中,其值为1.

专业提示:始终打印/记录异常的完整堆栈跟踪。

答案 2 :(得分:2)

让我在这里结合所有好的答案。

1)拆分你的方法,分别处理一件事。一个用于将文件读入strings [],一个用于处理字符串[],另一个用于调用前两个。

2)当你分开思考你想如何分裂时。正如@ m0skit0建议你应该用\ b来解决这个问题。

3)正如@jas建议你首先应该检查你的地图是否已经有了这个词。如果它确实增加了计数,如果没有将该词添加到地图中并将其设置为1。

4)要以您可能期望的方式打印出地图,请查看以下内容:

Map test = new HashMap();

for (Map.Entry entry : test.entrySet()){
  System.out.println(entry.getKey() + " " + entry.getValue());
}