【问题标题】:Read a .txt file and return a list of words with their frequency in the file读取一个 .txt 文件并返回一个单词列表及其在文件中出现的频率
【发布时间】:2014-12-05 21:34:48
【问题描述】:

到目前为止我有这个,但它只将 .txt 文件打印到屏幕上:

import java.io.*;

public class ReadFile {
    public static void main(String[] args) throws IOException {
        String Wordlist;
        int Frequency;

        File file = new File("file1.txt");
        BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
        String line = null;

        while( (line = br.readLine()) != null) {
            String [] tokens = line.split("\\s+");
            System.out.println(line);
        }
    }
}

谁能帮我打印一个单词列表和单词频率?

【问题讨论】:

  • 这个txt文件是什么格式的?
  • 它只是一个标题和一个保存为file1.txt的段落

标签: java filereader


【解决方案1】:

它必须是 Java 语言吗?这样就可以了:

sed 's/[^A-Za-z]/\n/g' filename.txt | sort | uniq -c

基本上,将任何非字母字符转换为换行符,对项目列表进行排序,然后让 uniq 计算出现次数。只需丢弃输出的第一行,即空行数。这运行速度很快,编码速度也更快。

您可以根据口味调整正则表达式,例如包括数字[A-Za-z0-9] 或外语重音字符[A-Za-zàèìòù]。

【讨论】:

  • 您可能应该在正则表达式中添加撇号;不想把“dog's”这个词当作“dog”和“s”来对待。也许连字符也是如此,但这更像是一个灰色地带。
【解决方案2】:

做这样的事情。我假设文件中只能出现逗号或句号。否则,您还必须删除其他标点符号。我正在使用 TreeMap,因此地图中的单词将按自然字母顺序存储

  public static TreeMap<String, Integer> generateFrequencyList()
    throws IOException {
    TreeMap<String, Integer> wordsFrequencyMap = new TreeMap<String, Integer>();
    String file = "/tmp/lorem.txt";
    BufferedReader br = new BufferedReader(new FileReader(file));
    String line;
    while( (line = br.readLine()) != null){
         String [] tokens = line.split("\\s+");
      for (String token : tokens) {
        token = removePunctuation(token);
        if (!wordsFrequencyMap.containsKey(token.toLowerCase())) {
          wordsFrequencyMap.put(token.toLowerCase(), 1);
        } else {
          int count = wordsFrequencyMap.get(token.toLowerCase());
          wordsFrequencyMap.put(token.toLowerCase(), count + 1);
        }
      }
    }
    return wordsFrequencyMap;
  }

  private static String removePunctuation(String token) {
    token = token.replaceAll("[^a-zA-Z]", "");
    return token;
  }

测试的主要方法如下所示。为了获得百分比,您可以通过遍历地图并添加所有值来获得所有单词的计数,然后再进行第二次传递以获取百分比。顺便说一句,如果这是更大工作的一部分,您还可以查看 apache commons 数学库以计算 Frequency distributions。如果你使用他们的Frequency 类,你可以继续添加所有的单词,然后在最后得到描述性统计。

  public static void main(String[] args) {
    try {
      int totalWords = 0;   
      TreeMap<String, Integer> freqMap = generateFrequencyList();
      for (String key : freqMap.keySet()) {
        totalWords += freqMap.get(key);
      }

      System.out.println("Word\tCount\tPercentage");
      for (String key : freqMap.keySet()) {
         System.out.println(key+"\t"+freqMap.get(key)+"\t"+((double)freqMap.get(key)*100.0/(double)totalWords));    
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

【讨论】:

  • 太棒了,非常感谢。它包含的标点符号是 , 。 : ; !所以对于 removePunctuation 我要做的就是添加 .replaceAll(":", "").replaceAll(";","").replaceAll("!","")?
  • 我还应该显示百分比并将它们全部打印在 3 列中(单词、频率和百分比)。我怎样才能把它变成那种格式?
【解决方案3】:

创建一个哈希映射

HashMap<String, Integer> occurrences = new HashMap<String, Integer>();

遍历每一行的数组

for(String word: tokens) {
  // Do stuff
}

然后检查每个单词之前是否已经阅读过该单词

if(occurrences.containsKey(word))
    occurrences.put(word, occurrences.get(word)+1);
else
    occurrences.put(word, 1);

完整版:

String Wordlist;
int Frequency;

File file = new File("file1.txt");
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file)));

HashMap<String, int> occurrences = new HashMap<String, int>();

String line = null;

while( (line = br.readLine()) != null){
    String [] tokens = line.split("\\s+");

    for(String word: tokens) {
        if(occurences.contains(word))
            occurences.put(word, occurences.get(word)+1);
        else
            occurences.put(word, 1);
    } 
}

可能是一个错字,尚未测试,但这应该可以完成工作。

【讨论】:

  • 我在“HashMap 出现次数 = new HashMap();”行中得到“需要意外类型;参考;找到:int”
  • 已更正,在不假思索地打字时会发生这种情况。 HashMaps 需要类型作为参数,在这种情况下是整数,而不是整数。
  • 包含关键字(单词),不包含(单词)
  • 感谢您的补充,没有智能感知我迷路了。 ;)
猜你喜欢
  • 2011-07-03
  • 2012-09-23
  • 2021-03-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多