《钦定版圣经》唯一单词统计程序性能瓶颈优化求助
优化圣经单词统计代码:从慢到快的核心改造
嘿,我瞅了下你这段统计圣经单词的代码,运行慢的核心问题一眼就能看出来——你用了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
相关产品推荐
相关产品推荐

