跳转到主内容
趣航编程网 - 趣学编程,启航技术之路!

如何使用 Scanner 统计相邻重复数字组的数量(非重复字符对数量)

本文详解如何正确统计字符串中“相邻重复数字组”的数量(如 "1 1 2 7 7 7 7 3 3 5 3" 中的 "1 1"、"7 7 7 7"、"3 3" 共 3 组),纠正初学者常见的边界越界与逻辑误判问题。 本文详解如何正确统计字符串中“相邻重复数字组”的数量(如 "1 1 2 7 7 7 7 3 3 5 3" 中的 "1 1"、"7 7 7 7"、"3 3" 共 3 组),纠正初学者常见的边界越界与逻辑误判问题。 在解决 adjacentDuplicatesCount 问题时,核心目标是: 统计“连续相同数字构成的块”的数量,而非统计所有相邻相等的字符对 。例如输入 "1 1 2 7 7 7 7 3 3 5 3"(含空格),应识别出三组相邻重复:"1 1"(1组)、"7 7 7 7"(1组)、"3 3"(1组)→ 总计 3 组 。 你原始代码的问题在于: 使用 Scanner 拼接为无空格字符串(如 "11277773353"),导致 '1','1' → '1','2' → '2','7' …… 这样会把 "7777" 错误拆解为 3 对相邻相等 (即索引 3=4、4=5、5=6),再加上 "11" 和 "33" 各 1 对,共 5 对;而你的循环范围 i < result.length() - 1 实际遍历了 i=1 到 i=length-2,又漏掉首对,最终凑出 4 —— 这正是“多算 1”的根源。 ✅ 正确思路是: 逐个读取 token(数字),比较当前 token 与前一个 token 是否相同;若相同且前一个已形成重复,则仅在“重复开始处”计数 1 次 。 以下是推荐的简洁、健壮实现:
public static int adjacentDuplicatesCount(String str) { Scanner reader = new Scanner(str); int count = 0; String prev = null; while (reader.hasNext()) { String curr = reader.next(); // 当前数字等于前一个,且之前尚未计入该组 → 计数+1 if (prev != null && curr.equals(prev)) { count++; // 关键:跳过后续连续相同的项(如7777只计1次) while (reader.hasNext() && reader.peek().equals(curr)) { reader.next(); // 消耗掉后续重复项 } } prev = curr; } reader.close(); return count; }
⚠️ 注意事项: 必须调用 reader.close() 防止资源泄漏; 使用 reader.peek()(需 Java 19+)可预览下一个 token 而不消耗它;若使用低版本 JDK,请改用临时变量缓存:
String next = null; while (reader.hasNext()) { String curr = next != null ? next : reader.next(); next = reader.hasNext() ? reader.next() : null; // ... 逻辑同上,用 next 替代 peek() }
不要拼接字符串后遍历字符 —— 空格语义丢失,数字位数混淆(如 "11" 和 "1 1" 在拼接后无法区分); Map 方案(答案中提供)实际统计的是「出现次数 ≥2 的数字种类数」,例如 "7 7 7 7" 和 "7 7" 都只算 1 次,但它 无法区分是否相邻 ("7 1 7" 也会被误计),因此不符合题意中“Adjacent Duplicates”的严格定义。 ? 总结:相邻重复组计数 = 一次遍历 + 状态记忆(prev)+ 贪心跳过(连续相同则跳过后续)。这既是算法思维训练,也是 Scanner 实际应用的典型范式。

相关文章