使用Java并行数组统计单词频率的实现疑问及代码调试求助
解决单词频率统计的问题
看起来你在统计单词频率的时候走了点弯路,我来帮你梳理下问题,再给出可行的方案~
先说说你代码里的几个明显问题
- 首先
Scanner scnr没有初始化,main方法里直接用scnr会编译报错,得加上Scanner scnr = new Scanner(System.in); currWord在main方法里没有声明类型,要加上String currWord;getFrequencyOfWord方法的逻辑完全错了:你创建了一个countArr数组,但其实你只需要统计currWord在wordsList里出现的次数,不需要数组来存每个位置的计数,而且最后返回countArr[i]的时候,i已经等于listSize了,这会直接抛出数组越界异常- 输入处理有问题:
scnr.nextInt()只会读取数字,后面的换行符会留在输入流里,导致scnr.nextLine()读取到空字符串,拆分后的数组可能不符合预期,得在nextInt()之后调用scnr.nextLine()吃掉换行
关于你疑惑的「是否需要两层嵌套数组」
答案是完全不需要。其实有两种更高效的方式:
方式1:用HashMap(推荐,简洁高效)
HashMap可以直接把单词作为key,出现次数作为value,遍历一次数组就能完成统计,不需要嵌套循环(除非你要去重输出)。
方式2:用数组(如果必须用数组的话)
可以用一个数组存不重复的单词,另一个数组对应存频率,但需要先遍历原数组去重,再统计每个不重复单词的次数,不过这种方式效率不如HashMap。
修正后的代码示例
方案1:HashMap版本(最常用)
import java.util.HashMap; import java.util.Scanner; public class LabProgram { // 获取单个单词的频率(如果需要单独调用的话) public static int getFrequencyOfWord(String[] wordsList, String currWord) { int count = 0; for (String word : wordsList) { if (word.equals(currWord)) { // 字符串比较用equals,不要用compareTo(除非要排序) count++; } } return count; } public static void main(String[] args) { Scanner scnr = new Scanner(System.in); int size = scnr.nextInt(); scnr.nextLine(); // 吃掉nextInt后的换行符 String[] array = scnr.nextLine().split(" "); // 用HashMap统计所有单词频率 HashMap<String, Integer> frequencyMap = new HashMap<>(); for (String word : array) { frequencyMap.put(word, frequencyMap.getOrDefault(word, 0) + 1); } // 输出每个单词的频率(去重输出) for (String word : frequencyMap.keySet()) { System.out.println(word + ": " + frequencyMap.get(word)); } // 如果需要按照原数组顺序输出(包括重复的单词),可以替换成这段: // for (String word : array) { // System.out.println(word + ": " + getFrequencyOfWord(array, word)); // } } }
方案2:数组版本(满足你想用数组的需求)
import java.util.Scanner; public class LabProgram { public static int getFrequencyOfWord(String[] wordsList, String currWord) { int count = 0; for (String word : wordsList) { if (word.equals(currWord)) { count++; } } return count; } // 获取不重复的单词数组 public static String[] getUniqueWords(String[] wordsList) { String[] tempArr = new String[wordsList.length]; int uniqueCount = 0; for (String word : wordsList) { boolean isExist = false; for (int i = 0; i < uniqueCount; i++) { if (tempArr[i].equals(word)) { isExist = true; break; } } if (!isExist) { tempArr[uniqueCount] = word; uniqueCount++; } } // 裁剪成实际长度的数组 String[] uniqueWords = new String[uniqueCount]; System.arraycopy(tempArr, 0, uniqueWords, 0, uniqueCount); return uniqueWords; } public static void main(String[] args) { Scanner scnr = new Scanner(System.in); int size = scnr.nextInt(); scnr.nextLine(); String[] array = scnr.nextLine().split(" "); String[] uniqueWords = getUniqueWords(array); int[] frequencyArr = new int[uniqueWords.length]; // 统计每个不重复单词的频率 for (int i = 0; i < uniqueWords.length; i++) { frequencyArr[i] = getFrequencyOfWord(array, uniqueWords[i]); } // 输出结果 for (int i = 0; i < uniqueWords.length; i++) { System.out.println(uniqueWords[i] + ": " + frequencyArr[i]); } } }
几个关键知识点提醒
- 字符串比较要用
equals(),compareTo()是用来比较字典序的,返回0只是说明相等,但用equals()更直观 - 处理输入的时候,
nextInt()之后一定要记得调用nextLine()吃掉换行,否则会读取到空内容 - 统计频率优先用HashMap,时间复杂度是O(n),而用数组嵌套循环的话时间复杂度是O(n²),数据量大的时候效率差很多
内容的提问来源于stack exchange,提问作者jope
相关产品推荐
相关产品推荐

