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

《钦定版圣经》唯一单词统计程序性能瓶颈优化求助

优化圣经单词统计代码:从慢到快的核心改造

嘿,我瞅了下你这段统计圣经单词的代码,运行慢的核心问题一眼就能看出来——你用了ArrayList.contains()来检查单词是否存在,再加上一些没必要的冗余逻辑,直接把时间复杂度拉到了O(n²),圣经这种超大规模文本肯定扛不住。咱们来一步步优化:

问题出在哪?

  • ArrayList.contains()的低效:每次调用这个方法,都会遍历整个列表检查是否存在目标元素。圣经的单词量成千上万,遍历次数会指数级增长,速度自然慢得离谱。
  • 冗余的allWords列表:你把每个扫描到的单词都存入这个列表,完全是浪费内存——统计唯一单词和频率根本不需要保存所有单词的实例。
  • 逻辑小bug:你在else分支里调用newWord.incrementFrequency(),但这个newWord是新创建的对象,根本没关联到已有的实例,等于白加了,频率统计完全不对。

优化方案:用哈希表实现O(1)级查找

咱们换用HashMap来存储单词和对应的统计实例,因为HashMap的查找、插入操作都是接近O(1)的时间复杂度,直接把整体时间复杂度降到O(n)。

优化后的代码示例

import java.io.File;
import java.io.FileNotFoundException;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import java.util.ArrayList;

public int parseBook(File fileName) throws FileNotFoundException {
    // 用try-with-resources自动关闭Scanner,避免资源泄漏
    try (Scanner scan = new Scanner(fileName)) {
        // 以单词字符串为Key,Word实例为Value,快速查找
        Map<String, Word> wordFrequencyMap = new HashMap<>();
        
        while (scan.hasNext()) {
            // 转小写,避免大小写差异导致重复统计(比如"The"和"the"算同一个单词)
            String currentWord = scan.next().toLowerCase();
            
            if (wordFrequencyMap.containsKey(currentWord)) {
                // 单词已存在,直接累加频率
                wordFrequencyMap.get(currentWord).incrementFrequency();
            } else {
                // 单词不存在,创建新实例并存入Map
                Word newWord = new Word(currentWord);
                wordFrequencyMap.put(currentWord, newWord);
            }
        }
        
        // 将唯一单词转换为列表(如果需要保留原需求的uniqueWordList)
        List<Word> uniqueWordList = new ArrayList<>(wordFrequencyMap.values());
        
        // 查找并输出频率最高的单词
        Word mostFrequentWord = Collections.max(uniqueWordList, 
            Comparator.comparingInt(Word::getFrequency));
        System.out.printf("频率最高的单词:%s,出现次数:%d%n", 
            mostFrequentWord.getWord(), mostFrequentWord.getFrequency());
        
        return uniqueWordList.size();
    }
}

额外注意事项

  • Word类的必要重写:如果你的Word类还没重写equals()和hashCode()方法,建议基于word字段重写(虽然这次用String当Key不影响,但后续如果需要比较Word实例会用到)。
  • 处理特殊字符:圣经文本里可能包含标点(比如逗号、句号),可以在获取currentWord时用正则去掉,比如currentWord = scan.next().replaceAll("[^a-zA-Z]", "").toLowerCase();,避免把"God,"和"God"当成不同单词。
  • 内存优化:如果不需要保留Word实例,甚至可以直接用HashMap<String, Integer>来存单词和频率,进一步减少内存占用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 04:48:55