使用Java记录四级试卷中的单词出现频率

1. 前言

实现的功能是,记录四级试卷中所有单词出现频率,并将单词以频率高低的方式进行排序,当然不仅是试卷,其他的文章都可以

2. 思路

怎么使用Java记录一张四级卷子里中所有的单词呢

  • 读取到文章所有的内容

  • 区分单词与其他字符,用map将单词与出现次数建立映射

  • map排序

3. 实现

3.1 读取文章所有内容

首先在网上下载四级卷子的word版,将其内容复制到txt文本中,我们使用Java读取这个txt文本里的所有内容

使用的是Java 7中新增的NIO包中的Files类和Path类来读取文件,非常方便,确保JDK版本在1.7以上

// 参数填上需要读取文件的路径
Path path = Paths.get("D:\code\words\2015年6月.txt"); 

BufferedReader br = Files.newBufferedReader(path);
String line = null;
while ((line = br.readLine()) != null) {
  System.out.println(line);
}

3.2 区分单词与其他字符,用map将单词与出现次数建立映射

一开始想使用正则的方法来将单词拆分,但发现会比较麻烦,因为单词拆分原则比较多,有空格,有括号,引号以及句号等等

还有一个重要原因是因为,我想把单词第一个大写的字母转换为小写,这样在统计频率的时候,会更加利于我们操作

所以采用了下面的方法

while ((line = br.readLine()) != null) {
  StringBuilder word = new StringBuilder();
  for (int j = 0; j < line.length(); j++) {
    char ch =line.charAt(j);
    if (ch >= 'a' && ch <= 'z') {
      word.append(ch);
    } else if (ch >= 'A' && ch <= 'Z') { // 如果单词是大写,把它转换为小写形式,方便统计次数
      word.append((char) (ch + 32));
    } else if (word.toString().length() > 1) {// 如果遇到不是单词的字符,而且单词不是一个字母
        String word_string = word.toString();
        // 如果单词不存在, 将单词填入并初始化为1次
        if (!map.containsKey(word_string)) {
          map.put(word_string, 1);
        } else {
            // 如果单词存在,找到该单词对应的频率,将其加1,重新覆盖
          map.put(word_string, map.get(word_string) + 1);
        }
        // 清空StringBuilder, 计入下个单词
        word.setLength(0);
      }
  }
}
3.3 将map排序

用到Collections.sort()方法和map的内部接口Map.Entry

Map.Entry是map的一个内部接口,它表示map的一个实体(也就是一个key-value对)

用以下方法可以实现,将Map按value以降序的方式排序

List<Map.Entry<String, Integer>> infoIds = new ArrayList<>(map.entrySet());

Collections.sort(infoIds, new Comparator<Map.Entry<String, Integer>>() {
  @Override
  public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {
    return (o2.getValue() - o1.getValue());
  }
});

4. 代码

以下是实现的总代码,可计算多张卷子

package indi.zmj.corejava.bit;

import java.io.BufferedReader;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;

/**
 * @author zmj
 * @create 2018/11/11
 */
public class splitWords {

  public void readPapers(String[] url) throws IOException {
    
    TreeMap<String, Integer> map = new TreeMap<>();

    for (int i = 0; i < url.length; i++) {
      Path path = Paths.get(url[i]);
      BufferedReader br = Files.newBufferedReader(path);
      String line = null;
      // 读取文件中的每一行, 并用StringBuilder统计每个单词
      while ((line = br.readLine()) != null) {
        StringBuilder word = new StringBuilder();
        for (int j = 0; j < line.length(); j++) {
          char ch = line.charAt(j);
          if (ch >= 'a' && ch <= 'z') {
            word.append(ch);
          } else if (ch >= 'A' && ch <= 'Z') {
            // 如果单词是大写,把它转换为小写形式,方便统计次数
            word.append((char) (ch + 32));
          } else if (word.toString().length() > 1) {
            String word_string = word.toString();
            // 如果单词不存在, 将单词填入并初始化为1次
            if (!map.containsKey(word_string)) {
              map.put(word_string, 1);
            } else {
              // 如果单词存在,找到该单词对应的频率,将其加1,重新覆盖
              map.put(word_string, map.get(word_string) + 1);
            }
            // 清空StringBuilder, 计入下个单词
            word.setLength(0);
          }
        }
      }
      br.close();
    }

    List<Map.Entry<String, Integer>> infoIds = new ArrayList<>(map.entrySet());

    Collections.sort(infoIds, new Comparator<Map.Entry<String, Integer>>() {
      @Override
      public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {
        return (o2.getValue() - o1.getValue());
      }
    });
    for (int i = 0; i < infoIds.size(); i++) {
      System.out.printf("单词:%12s   出现了:%d次\n", infoIds.get(i).getKey(), infoIds.get(i).getValue());
    }
  }

  public static void main(String[] args) throws IOException {
    String[] url = {"D:\\code\\words\\2015年6月.txt", "D:\\code\\words\\2015年12月.txt"
            , "D:\\code\\words\\2016年6月.txt", "D:\\code\\words\\2016年12月.txt", 
            "D:\\code\\words\\2017年12月.txt", "D:\\code\\words\\2018年6月.txt"};
    new splitWords().readPapers(url);
  }
}

5. 效果图

截取了其中一部分效果
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值