【日耕一题】4. 较为复杂情况下的求和

你好,我是林森lsjs

我的Github地址: sqyCoder (Qiyang) · GitHub

欢迎来到日耕一题,跟着我。今天这道题,表面是求和,实际上却在考你 Scanner 的"智能分词"异常规避

其实,Java 的 Scanner 早就给我们准备好了一套优雅的"跳过非整数"方案------hasNextInt()

目录

一、题目完整解读

原题

拆解所有要求

二、核心知识点

[1. Scanner 的默认分词规则](#1. Scanner 的默认分词规则)

[2. hasNextInt() 与 nextInt() 的配合](#2. hasNextInt() 与 nextInt() 的配合)

[3. 为什么要用 hasNext() 外层循环](#3. 为什么要用 hasNext() 外层循环)

[三、分步代码编写 + 逐行讲解](#三、分步代码编写 + 逐行讲解)

[1. 第一步:创建 Scanner,初始化累加器](#1. 第一步:创建 Scanner,初始化累加器)

[2. 第二步:循环读取每个 token](#2. 第二步:循环读取每个 token)

[3. 第三步:输出结果并关闭](#3. 第三步:输出结果并关闭)

四、完整可运行代码

五、执行流程全复盘(重点)


一、题目完整解读

原题

较为复杂情况下的求和

计算一个给定序列的整数和,序列中可能会混入无关的字母,求和的时候需要忽略。

输入格式

输入为一行,元素直接使用空格分割。

输出格式

输出为序列整数部分的和。

输入样例

复制代码
1 2 3 a 4 5

输出样例

复制代码
15

拆解所有要求

  1. 读一整行:元素用空格分割,这一点和上一题一样。

  2. 混合内容:整数里夹着字母(甚至可能夹着符号),但只看整数。

  3. 忽略无关字符:凡是不是整数的元素,统统当不存在。

  4. 输出仅为和:一个干净的数字,不能多任何汉字或冒号。

  5. 隐式坑位 :如果元素是 "123a" 这种半数字半字母的,它算整数吗?题目没明说,但从样例看,只有纯整数的才算,沾一点字母都得跳过。


二、核心知识点

1. Scanner 的默认分词规则

Scanner 在调用 next()、nextInt()、hasNextInt() 等方法时,会 自动以空白字符(空格、换行、制表符)作为分隔符 ,把输入拆成一个一个的"词"(token)。

也就是说:

输入 "1 2 3 a 4 5" 会被自动切成:"1", "2", "3", "a", "4", "5"

你不用自己调 split,Scanner 已经给你切好了。

即使输入是连续多个空格、换行混排,Scanner 也都能正确跳过,不会产生空字符串 ,天然避开了 split 的空字符串坑。

2. hasNextInt() 与 nextInt() 的配合

hasNextInt() 会检查 下一个 token 能否被解析成一个合法的 int 整数 (支持正负号),但它 不会消耗掉这个 token

如果可以解析成整数,它就返回 true,然后你就可以放心地用 nextInt() 把这个数读出来累加。

如果不能解析(比如下一个 token 是 "a""123a"),就返回 false,你只需要用 next() 把它当作普通字符串读走并丢掉,循环继续。

这套组合拳,完美实现了"是整数就累加,不是整数就跳过"。

3. 为什么要用 hasNext() 外层循环

while (sc.hasNext()) 用来判断输入流里还有没有下一个 token。

只要没到文件末尾(EOF),循环就会一直跑,逐个处理每一个 token。

本地运行小提示:在 IDE 或命令行运行时,输入完样例后程序不会自动结束,你需要手动输入 EOF:

  • Windows:按 Ctrl + Z 然后回车

  • Mac / Linux:按 Ctrl + D

OJ(在线判题系统)会把输入文件直接重定向给程序,会自动产生 EOF,你完全不用操心。


三、分步代码编写 + 逐行讲解

1. 第一步:创建 Scanner,初始化累加器

java 复制代码
Scanner sc = new Scanner(System.in);
int sum = 0;  // 初始值必须为 0

2. 第二步:循环读取每个 token

java 复制代码
while (sc.hasNext()) {         // 还有下一个 token 吗?
    if (sc.hasNextInt()) {    // 这个 token 是整数吗?
        sum += sc.nextInt();  // 是整数,读出来累加
    } else {
        sc.next();            // 不是整数,读走并丢弃
    }
}

为什么 else 里面不能什么都不写?

如果你只判断不读走,这个非整数 token 会永远卡在输入流里,hasNext() 一直为 true,形成 死循环 。所以必须用 next() 把它"吃掉"。

3. 第三步:输出结果并关闭

java 复制代码
System.out.println(sum);
sc.close();

输出只有一行数字,绝对不能加任何修饰词。


四、完整可运行代码

java 复制代码
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        // 1. 创建扫描器,连接标准输入
        Scanner sc = new Scanner(System.in);
        int sum = 0;  // 累加和,初始化为 0

        // 2. 循环读取每一个 token,直到 EOF
        while (sc.hasNext()) {
            // 2.1 如果下一个 token 可以解析成 int 整数
            if (sc.hasNextInt()) {
                sum += sc.nextInt();  // 读出整数并累加
            } else {
                // 2.2 否则就是一个非整数 token(字母、带字母的串等)
                sc.next();  // 读出来扔掉,继续下一个
            }
        }

        // 3. 输出最终的和
        System.out.println(sum);

        sc.close(); // 关闭资源,好习惯
    }
}

五、执行流程全复盘(重点)

我们拿样例输入 "1 2 3 a 4 5",一步步跑一遍程序,让你看清楚每个变量的变化。

  1. 程序启动

    sum = 0,Scanner 准备好读取输入。

  2. 第一次循环

    sc.hasNext()true(还有 token)

    sc.hasNextInt()true(token 是 "1",能转成整数)

    执行 sum += sc.nextInt() → 读出 1sum = 1

  3. 第二次循环

    hasNext()true

    hasNextInt()true(token "2"

    sum = 1 + 2 = 3

  4. 第三次循环

    hasNextInt()true(token "3"

    sum = 3 + 3 = 6

  5. 第四次循环

    hasNextInt()false(token "a"

    执行 sc.next() → 读出 "a" 并丢弃,sum 仍为 6

  6. 第五次循环

    hasNextInt()true(token "4"

    sum = 6 + 4 = 10

  7. 第六次循环

    hasNextInt()true(token "5"

    sum = 10 + 5 = 15

  8. 第七次循环

    hasNext()false(EOF,没有更多 token 了)

    循环结束。

  9. 输出 15,程序退出。

六、总结

核心 :用 ScannerhasNextInt() 自动切分 token 并判断------是整数就 nextInt() 累加,不是就用 next() 扔掉。

优势 :代码极短,无需手动 split,自动避开连续空格的坑,负数也天然支持。

注意 :非整数必须用 next() 拿走,否则死循环;

本地运行按 Ctrl + Z(Windows)或 Ctrl + D(Mac/Linux)结束输入。

一句话:利用 Scanner 的智能过滤,让只读整数求和变成最简单的循环。

++就到这里,诸位共勉!++

相关推荐
咖啡八杯23 分钟前
GoF设计模式——中介者模式
java·后端·spring·设计模式
青石路4 小时前
记一次多JDK版本问题的排查,一坑套一坑,差点没爬上来
java
像我这样帅的人丶你还7 小时前
Java 后端详解(五):Redis 缓存
java·后端·全栈
plainGeekDev9 小时前
GreenDAO → Room
android·java·kotlin
亦暖筑序14 小时前
Java 8老系统AI Workflow实战:把一次性AI对话升级成可恢复工作流
java·后端
敲代码的彭于晏15 小时前
Bean 生命周期完全图解:前端同学也能看懂的 Spring 核心机制
java·前端·后端
plainGeekDev16 小时前
ButterKnife → ViewBinding
android·java·kotlin
像我这样帅的人丶你还1 天前
Java 后端详解(四):分页与搜索
java·javascript·后端
她的男孩1 天前
数据权限为什么不能只靠注解?Forge 的 Mapper 层 SQL 改写源码拆解
java·后端·架构
tntxia1 天前
Mybatis的日志输入
java