实验原理:
因为本次实验首先要从文件中读入每篇论文的关键词,我们需要创建一个缓冲流对象(BufferedReader bufferRead)对文件进行一行一行的读取(while((str = bufferRead.readLine())!=null)循环读取),读取出每行的字符串。因为每行的中的关键词是用分号‘;’进行分割的,所以使用str.split(";")将拆分每行的关键词,并将该行的关键词赋值给数组(String[] words = str.split(";");),再对每个关键词使用trim()去除字符串两端的空格。再创建一个哈希表,字符串作为键,整型数据作为值,用于记录关键词出现次数。当哈希表创建完成后根据值的大小进行逆序排序,再创建一个缓冲流对象(BufferedWriter bufferWrite)将“每个词+tab+词频”一行输入到“频次.txt”文件。
其中使用到了数组和哈希表这两个数据结构。使用数组的原因是因为数组能够将不同的关键词分开存储,便于区分不同关键词。使用哈希表的原因是它建立了关键词与词频的键值对关系,记录的不同关键词及其出现次数。
使用第一行数据为例:0 1 multidimensional knapsack problem;Machine learning;Meta RaPS;Path Relinking;Local search
将该行数据读入,经过分割之后存入数组,具体数组内容如下:
再创建一个哈希表,具体内容如下:
以上是对一行字符串的操作,对于整个文件来说,需要一行一行的执行操作,当有新关键词出现是,创建新的键值对(关键词为键,初始值为1),当遇到重复的关键词时,给对应的值+1。
二、最终代码
package task3;
//导入
import java.io.*;
import java.util.*;
public class WordFrequency {
public static void main(String args[]) {
File fRead = new File("关键词.txt");
File fWrite = new File("频次.txt");
//创建哈希表
Map<String, Integer> map = new HashMap<>();
try {
Writer out = new FileWriter(fWrite);
BufferedWriter bufferWrite = new BufferedWriter(out);
Reader in = new FileReader(fRead);
BufferedReader bufferRead = new BufferedReader(in);
String str = null;
//给哈希表赋值
while((str = bufferRead.readLine())!=null) {
String[] words = str.split(";");//-- 分隔符,默认为所有的空字符,包括空格、换行(\n)、制表符(\t)等。
//num -- 分割次数。默认为 -1, 即分隔所有。
for (String word : words) {
word = word.trim();
}
for (String word : words) {
if (map.containsKey(word)) {//检查hashMap中是否存在指定的key对应的映射关系
map.put(word, map.get(word) + 1);//找到对应的键给相应的值+1
} else {
map.put(word, 1);//添加键值对(key-value)
}
}
}
bufferRead.close();
//根据值的大小进行,得到一个排序的列表,这个列表有键和值,且是按照值的大小排好序的
List<Map.Entry<String, Integer>> list = new ArrayList<>(map.entrySet());
Collections.sort(list, (o1, o2) -> o2.getValue()-o1.getValue());
//通过循环逐个写入
for (Map.Entry<String, Integer> entry : list) {
bufferWrite.write(entry.getKey() + "\t" + entry.getValue() + "\n");
}
bufferWrite.close();
}
catch(IOException e) {
System.out.println(e.toString());
}
}
}
三、运行结果
输出文件结果截图