Java使用双层for循环统计句子单词出现次数的代码问题排查
代码错误点
- 计数器
countOfOccurence初始化位置错误:全局定义的计数器仅在检测到map已存在当前单词时重置,处理每个新单词前都需要将计数器重置为1,否则会沿用前一个单词的统计值,导致计数错误。 put操作放在内层循环内部:每次j迭代都会执行put操作,属于冗余操作,应该等内层循环遍历完所有后续单词、统计完总出现次数后,再将单词和对应次数存入map。- 遗漏末尾单词统计:当外层循环i走到数组最后一个索引时,内层j循环从i+1开始不会执行,当前单词不会被存入map,会漏统计仅出现1次的末尾单词。
getWords方法逻辑缺陷:一是将所有单词转为全小写,导致最终输出的单词都是小写,不符合预期输出的首字母大写格式;二是未对处理后的字符串做trim操作,若原字符串首尾有空格,split后会生成无效空字符串元素。
修正后完整代码
package corejava; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; public class DuplicateStringOccurence { public static void main(String[] args) { String myString = " Java is a language. java is easy and i like Java"; String[] wordsInMySentence = getWords(myString); Map<String, Integer> myMap = new HashMap<>(); // 外层循环遍历每个单词 for(int i=0;i<wordsInMySentence.length;i++) { String currentWord = wordsInMySentence[i]; // 已统计过的单词直接跳过 if (myMap.containsKey(currentWord.toLowerCase())) { continue; } // 每个新单词统计前重置计数器 int countOfOccurence = 1; // 内层循环统计后续相同单词 for(int j=i+1;j<wordsInMySentence.length;j++) { if (currentWord.equalsIgnoreCase(wordsInMySentence[j])) { countOfOccurence++; } } // 统计完成后存入map,key统一转小写用于去重,后续输出时格式化 myMap.put(currentWord.toLowerCase(), countOfOccurence); } // 按要求格式输出,首字母大写其余小写 for (Entry<String, Integer> entry : myMap.entrySet()) { String key = entry.getKey(); String formatKey = key.substring(0,1).toUpperCase() + key.substring(1); System.out.print(formatKey + "=" + entry.getValue() + ", "); } } private static String[] getWords(String myString) { // 移除非字母空格的字符,去除首尾空格后按空格拆分,不转全小写保留原格式 String[] wordsInMySentence = myString.replaceAll("[^a-zA-Z ]", "") .trim() .split("\\s+"); return wordsInMySentence; } }
运行后输出符合预期,可根据需要调整输出格式去掉末尾的逗号。
内容的提问来源于stack exchange,提问作者mack
相关产品推荐
相关产品推荐

