Java二叉树文本分析程序开发求助:禁用java.collections
Java文本分析程序分步实现方案
因为不能使用java.collections包,且需要基于二叉树+自定义链表实现,下面是完整的分步实现代码和说明:
1. 自定义行号链表
用来存储每个单词出现的所有行号,实现基础的添加和字符串转换功能:
public class LineNumberList { private Node head; private Node tail; // 链表节点内部类 private class Node { int lineNumber; Node next; Node(int lineNumber) { this.lineNumber = lineNumber; this.next = null; } } // 添加行号到链表 public void add(int lineNumber) { Node newNode = new Node(lineNumber); if (head == null) { head = newNode; tail = newNode; } else { tail.next = newNode; tail = newNode; } } // 转成逗号分隔的字符串,方便输出 @Override public String toString() { StringBuilder sb = new StringBuilder(); Node current = head; while (current != null) { sb.append(current.lineNumber); if (current.next != null) { sb.append(", "); } current = current.next; } return sb.toString(); } }
2. 二叉树节点类
每个节点存储单词、出现次数、行号链表,以及左右子节点引用:
public class WordNode { public String word; public int count; public LineNumberList lineNumbers; public WordNode left; public WordNode right; public WordNode(String word, int lineNumber) { this.word = word.toLowerCase(); // 统一转小写,避免大小写重复计数 this.count = 1; this.lineNumbers = new LineNumberList(); this.lineNumbers.add(lineNumber); this.left = null; this.right = null; } // 添加行号到当前单词的行号列表 public void addLineNumber(int lineNumber) { this.count++; this.lineNumbers.add(lineNumber); } }
3. 二叉搜索树实现
负责按字母顺序维护单词节点,提供插入、遍历、CSV导出功能:
public class WordBinaryTree { private WordNode root; private int totalWords; // 统计总单词数 public WordBinaryTree() { root = null; totalWords = 0; } // 对外暴露的插入方法 public void insert(String word, int lineNumber) { totalWords++; word = word.toLowerCase().trim(); if (word.isEmpty()) return; // 跳过空字符串 root = insertRecursive(root, word, lineNumber); } // 递归插入节点(二叉搜索树逻辑,按字母顺序排序) private WordNode insertRecursive(WordNode current, String word, int lineNumber) { if (current == null) { return new WordNode(word, lineNumber); } int compareResult = word.compareTo(current.word); if (compareResult == 0) { // 单词已存在,添加行号并计数+1 current.addLineNumber(lineNumber); } else if (compareResult < 0) { // 插入左子树 current.left = insertRecursive(current.left, word, lineNumber); } else { // 插入右子树 current.right = insertRecursive(current.right, word, lineNumber); } return current; } // 中序遍历(得到按字母顺序排列的单词列表) public void inorderTraversal() { inorderRecursive(root); } private void inorderRecursive(WordNode current) { if (current != null) { inorderRecursive(current.left); // 计算相对频率 double frequency = (double) current.count / totalWords * 100; System.out.printf("单词: %-15s 出现次数: %d 相对频率: %.2f%% 行号: %s%n", current.word, current.count, frequency, current.lineNumbers); inorderRecursive(current.right); } } // 导出CSV文件 public void exportToCsv(String filePath) { try (java.io.PrintWriter writer = new java.io.PrintWriter(new java.io.FileWriter(filePath))) { // 写入CSV表头 writer.println("单词,出现次数,相对频率(%),行号"); // 中序遍历写入每一行 exportRecursive(root, writer, totalWords); System.out.println("CSV文件已成功导出到: " + filePath); } catch (java.io.IOException e) { System.out.println("导出CSV失败: " + e.getMessage()); } } private void exportRecursive(WordNode current, java.io.PrintWriter writer, int totalWords) { if (current != null) { exportRecursive(current.left, writer, totalWords); double frequency = (double) current.count / totalWords * 100; writer.printf("%s,%d,%.2f,%s%n", current.word, current.count, frequency, current.lineNumbers); exportRecursive(current.right, writer, totalWords); } } public int getTotalWords() { return totalWords; } }
4. 文本文件读取处理器
负责读取文本文件,逐行分割单词并插入到二叉树中:
public class TextProcessor { public static void processTextFile(String filePath, WordBinaryTree tree) { try (java.io.BufferedReader reader = new java.io.BufferedReader(new java.io.FileReader(filePath))) { String line; int lineNumber = 0; while ((line = reader.readLine()) != null) { lineNumber++; // 分割单词:按非字母字符分割,过滤空格、标点 String[] words = line.split("[^a-zA-Z]+"); for (String word : words) { if (!word.isEmpty()) { tree.insert(word, lineNumber); } } } } catch (java.io.IOException e) { System.out.println("读取文件失败: " + e.getMessage()); } } }
5. 主程序入口
整合所有模块,接收文件路径参数,执行分析并导出结果:
public class Main { public static void main(String[] args) { if (args.length < 1) { System.out.println("请指定要分析的文本文件路径,例如:java Main test.txt"); return; } String inputFilePath = args[0]; String outputCsvPath = "word_analysis_result.csv"; WordBinaryTree tree = new WordBinaryTree(); TextProcessor.processTextFile(inputFilePath, tree); // 输出统计结果到控制台 System.out.println("=== 文本分析结果 ==="); System.out.println("总单词数: " + tree.getTotalWords()); System.out.println("-------------------"); tree.inorderTraversal(); // 导出到CSV tree.exportToCsv(outputCsvPath); } }
使用说明
- 编译所有Java文件:
javac *.java - 运行程序并指定文本文件:
java Main your_text_file.txt - 程序会在控制台输出分析结果,并生成
word_analysis_result.csv文件
关键细节说明
- 所有单词统一转小写,避免大小写导致的重复统计(比如"Hello"和"hello"视为同一个单词)
- 分割单词时过滤掉非字母字符,避免标点符号被当成单词的一部分
- 二叉搜索树的中序遍历天然保证单词按字母顺序输出
- 相对频率计算保留两位小数,提升可读性
内容的提问来源于stack exchange,提问作者juju
相关产品推荐
相关产品推荐

