Java中如何将多文件词频统计结果以矩阵形式写入文件?
多文件词频统计矩阵实现方案
当然可以实现这个需求!我来给你拆解清晰的实现思路,再附上可落地的代码示例:
核心实现步骤
- 第一步:收集全局词汇库:先遍历所有要处理的文件,统计每个文件的词频,同时把所有出现过的单词收集到一个全局集合里——这就是矩阵的列标题来源,确保每个文件的统计结果都能对应到相同的列。
- 第二步:构建矩阵数据:用一个Map存储「文件名→该文件的词频Map」的映射,这样后续可以快速查询每个文件中某个单词的出现次数,没有出现的就填0。
- 第三步:格式化写入文件:按照你想要的表格格式,先输出表头(所有全局单词),再逐行输出每个文件名和对应的词频数值,最后把结果写入目标文件。
具体代码实现
首先,我们可以完善单个文件的词频统计方法(顺便优化编码和分词逻辑,解决你输出里的乱码问题):
// 统计单个文件的词频,支持指定UTF-8编码,同时做简单的单词清洗 public Map<String, Integer> getWordCount(String filePath) { Map<String, Integer> wordMap = new HashMap<>(); // 指定UTF-8编码读取文件,避免乱码 try (BufferedReader br = new BufferedReader( new InputStreamReader(new FileInputStream(filePath), StandardCharsets.UTF_8))) { String line; while ((line = br.readLine()) != null) { // 按空格分词,可根据需求调整分词规则 String[] words = line.split("\\s+"); for (String word : words) { // 清洗单词:去掉非字母字符(适配你的语言字符)、转小写 word = word.replaceAll("[^a-zA-Z\u00C0-\u017F]", "").toLowerCase(); if (!word.isEmpty()) { wordMap.put(word, wordMap.getOrDefault(word, 0) + 1); } } } } catch (IOException e) { System.err.println("读取文件失败:" + filePath); e.printStackTrace(); } return wordMap; }
然后是生成矩阵的核心逻辑:
import java.io.*; import java.util.*; import java.nio.charset.StandardCharsets; public class MaxDuplicateWordCount { // 上面的getWordCount方法放在这里 public void generateWordFrequencyMatrix(List<String> filePaths, String outputFilePath) { // 存储每个文件的词频:键是文件名,值是该文件的词频Map Map<String, Map<String, Integer>> fileWordCounts = new HashMap<>(); // 存储所有出现过的单词,用TreeSet自动按字典序排序,让表头更整齐 Set<String> allUniqueWords = new TreeSet<>(); // 第一步:遍历所有文件,收集词频和全局单词 for (String filePath : filePaths) { Map<String, Integer> wordCount = getWordCount(filePath); String fileName = new File(filePath).getName(); fileWordCounts.put(fileName, wordCount); allUniqueWords.addAll(wordCount.keySet()); } // 第二步:写入矩阵到目标文件 try (PrintWriter writer = new PrintWriter( new OutputStreamWriter(new FileOutputStream(outputFilePath), StandardCharsets.UTF_8))) { // 输出表头行 writer.print(" | "); for (String word : allUniqueWords) { // 用%-15s控制列宽,确保单词对齐,可按需调整数值 writer.printf("%-15s | ", word); } writer.println(); // 输出表头下方的分隔线 writer.print("---"); for (int i = 0; i < allUniqueWords.size(); i++) { writer.print("-------------------"); } writer.println(); // 输出每个文件的统计行 for (Map.Entry<String, Map<String, Integer>> entry : fileWordCounts.entrySet()) { String fileName = entry.getKey(); Map<String, Integer> wordCount = entry.getValue(); // 输出文件名列 writer.printf("%-20s | ", fileName); // 输出每个单词的出现次数,没有出现的填0 for (String word : allUniqueWords) { int count = wordCount.getOrDefault(word, 0); writer.printf("%-15d | ", count); } writer.println(); // 可选:每行之间添加分隔线,让表格更清晰 writer.print("---"); for (int i = 0; i < allUniqueWords.size(); i++) { writer.print("-------------------"); } writer.println(); } System.out.println("矩阵文件已成功生成:" + outputFilePath); } catch (IOException e) { System.err.println("写入矩阵文件失败"); e.printStackTrace(); } } public static void main(String[] args) { MaxDuplicateWordCount mdc = new MaxDuplicateWordCount(); // 替换成你要处理的文件路径列表 List<String> targetFiles = Arrays.asList( "C:/Users/Arnoldas/Desktop/Hamletas.txt", "C:/Users/Arnoldas/Desktop/Other_file.txt" ); // 替换成矩阵文件的输出路径 mdc.generateWordFrequencyMatrix(targetFiles, "C:/Users/Arnoldas/Desktop/word_freq_matrix.txt"); } }
额外优化建议
- 乱码问题:代码里已经指定了UTF-8编码读取和写入文件,能解决你当前输出里的乱码问题;
- 列宽调整:代码中的
%-15s和%-20s是控制列的宽度,你可以根据单词的平均长度调整数值,让表格更整齐; - 分词规则:如果你的文本有特殊的分词需求(比如连字符单词、缩写),可以修改
split的正则表达式或者自定义分词逻辑; - 性能优化:如果处理超大文件,可以考虑用流式处理或者多线程并行统计,但一般小文件用当前逻辑足够。
内容的提问来源于stack exchange,提问作者Arnas Arnelis
相关产品推荐
相关产品推荐

