
本文详解如何准确统计字符串数组中在每个字符串中至少出现一次的公共字符及其总出现次数(非全局频次),修正原始代码因重复计数导致的错误结果。
本文详解如何准确统计字符串数组中**在每个字符串中至少出现一次**的公共字符及其总出现次数(非全局频次),修正原始代码因重复计数导致的错误结果。
要解决“找出字符串数组中在所有索引位置(即每个字符串)均存在的字符,并统计其在全部字符串中出现的总次数”,关键在于:每个字符串对同一字符最多只贡献 1 次计数——即使该字符在一个字符串中重复出现(如 "been" 中 'e' 出现两次),也只应计入一次,否则会导致 'e':4 这类错误结果。
原始代码的问题在于:它对每个字符在每个字符串中的每一次出现都累加计数,未做去重。例如 "been" 贡献了 'b', 'e', 'e', 'n' 四次,其中 'e' 被加了两次,最终 repeated_char.get('e') 达到 4,误判为“在全部 4 个字符串中均出现”。
✅ 正确思路是:
- 遍历每个字符串;
- 对当前字符串,用
HashSet<character></character>记录已处理过的唯一字符; - 仅当某字符在当前字符串中首次出现时,才更新全局计数器;
- 最终,若某字符的全局计数等于字符串数组长度,则说明它在每个字符串中至少出现了一次,且其值即为它在各字符串中“是否出现”的总和(即跨字符串的出现次数)。
以下是修正后的完整实现:
import java.util.*;
public class RepeatedChar {
public static Map<character integer> repeatedChars(String[] str) {
if (str == null || str.length == 0) {
return Collections.emptyMap();
}
Map<character integer> globalCount = new HashMap();
for (String s : str) {
if (s == null) continue;
Set<character> seenInCurrent = new HashSet(); // 当前字符串已见字符
for (char c : s.toCharArray()) {
if (!seenInCurrent.contains(c)) {
globalCount.put(c, globalCount.getOrDefault(c, 0) + 1);
seenInCurrent.add(c);
}
}
}
// 筛选出在所有字符串中均出现的字符(count == str.length)
Map<character integer> result = new LinkedHashMap();
for (Map.Entry<character integer> entry : globalCount.entrySet()) {
if (entry.getValue() == str.length) {
result.put(entry.getKey(), entry.getValue());
}
}
return result;
}
public static void main(String[] args) {
String[] input = {"been", "bean", "bread", "boat"};
System.out.println(repeatedChars(input)); // 输出: {b=4}
}
}</character></character></character></character></character>
? 注意事项:
- 使用
LinkedHashMap可保持插入顺序(可选,便于调试); - 显式处理
null字符串,增强鲁棒性; -
getOrDefault(c, 0)替代冗长的null判断,更简洁安全; - 本解法统计的是“字符在多少个字符串中出现过”,而非“字符在整个数组中总共出现了几次”——这正是题意要求的语义(
'b':4表示'b'在全部 4 个字符串中均存在)。
? 扩展思考:若需同时返回字符在每个字符串中的具体位置或最大重复次数,可进一步封装为 Map<character list>></character> 或自定义结果类。但就本题目标而言,上述方案已精准、高效、可读性强。











