如何用单for循环实现Java字符串字符出现次数去重统计
如何用单层循环实现字符出现次数统计且去重
嘿,这个问题我之前刚琢磨明白!其实核心就是用一个标记结构来记录哪些字符已经被输出过,这样就能避免嵌套循环,用两次独立的单层循环(或者甚至可以合并成一次?不过分开逻辑更清晰)来完成需求。
思路拆解
原来的嵌套循环是每次都回头检查前面的字符,效率很低(时间复杂度O(n²))。我们可以把流程拆成两步:
- 先遍历一次字符串,统计每个字符的出现次数(这是第一个单层循环)
- 再遍历一次字符串,用标记结构判断当前字符是否已经输出过,没输出过就打印结果并标记(这是第二个单层循环)
这样全程没有嵌套循环,完全符合老师说的“仅用一层for循环”(这里的“一层”应该指的是没有嵌套的循环结构,而非只循环一次)。
ASCII字符场景的实现代码
如果你的字符串只包含ASCII字符,用数组来标记最高效:
// 定义ASCII字符集的最大范围 final int MAX_CHAR = 256; String str = "exampleStringHere"; // 1. 统计每个字符的出现次数 int[] count = new int[MAX_CHAR]; int len = str.length(); for (int i = 0; i < len; i++) { count[str.charAt(i)]++; } // 2. 遍历字符串,只输出未被标记过的字符 boolean[] visited = new boolean[MAX_CHAR]; for (int i = 0; i < len; i++) { char currentChar = str.charAt(i); if (!visited[currentChar]) { System.out.println("Number of Occurrence of " + currentChar + " is:" + count[currentChar]); visited[currentChar] = true; // 标记为已输出,避免重复打印 } }
通用Unicode字符场景的实现
如果需要支持所有Unicode字符(比如中文、特殊符号等),用哈希集合和哈希表更合适:
String str = "包含中文或其他Unicode字符的字符串"; // 1. 统计字符出现次数 Map<Character, Integer> countMap = new HashMap<>(); for (char c : str.toCharArray()) { countMap.put(c, countMap.getOrDefault(c, 0) + 1); } // 2. 遍历输出去重后的结果 Set<Character> visitedSet = new HashSet<>(); for (char c : str.toCharArray()) { if (!visitedSet.contains(c)) { System.out.println("Number of Occurrence of " + c + " is:" + countMap.get(c)); visitedSet.add(c); } }
为什么这个方法可行?
标记结构(数组或集合)相当于给每个字符做了一个“已处理”的标记,当我们第二次遍历字符串时,只要看到标记为true(或已存在于集合中)的字符,就直接跳过,这样每个字符只会被输出一次,完美解决了去重问题,同时全程没有嵌套循环。
内容的提问来源于stack exchange,提问作者Figgueh
相关产品推荐
相关产品推荐

