You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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);
    }
}

使用说明

  1. 编译所有Java文件:javac *.java
  2. 运行程序并指定文本文件:java Main your_text_file.txt
  3. 程序会在控制台输出分析结果,并生成word_analysis_result.csv文件

关键细节说明

  • 所有单词统一转小写,避免大小写导致的重复统计(比如"Hello"和"hello"视为同一个单词)
  • 分割单词时过滤掉非字母字符,避免标点符号被当成单词的一部分
  • 二叉搜索树的中序遍历天然保证单词按字母顺序输出
  • 相对频率计算保留两位小数,提升可读性

内容的提问来源于stack exchange,提问作者juju

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 05:15:31