【刷题日记】Java 快速热身——ACM 模式下的输入输出
相信我们已经非常熟悉 LeetCode 那种「站内文章核心代码」的写题模式,在这种模式下,我们可以更专注于代码逻辑本身。然而一些公司或学校的机考仍然使用 ACM 文件输入输出模式,在这种模式下需要对题目输入输出的逻辑进行额外的处理。
最最基本的输出写法。
1 | System.out.println("Hello Nowcoder!"); // 换行输出 IDEA 下快捷输入:sout |
java.util.Scanner
是 Java5 的新特征,我们可以通过 Scanner
类来获取用户的输入。
1 | // 创建 Scanner 对象的基本语法 |
输入时用到类 Scanner
类,里面有几个常用方法:
hasNext()
:用于判断是否还有输入的数据,常放在 while 循环中判断输入是否结束。next()
:读到空格就停止读取。适合读取单个字符或字符串。返回类型String
。nextLine()
:读取一整行数据,碰到换行则停止。返回类型String
next()
与 nextLine()
区别:
函数 | next() |
nextLine() |
---|---|---|
是否阻塞 | 一定要读取到有效字符后才可以结束输入 | |
结束符 | 对输入有效字符之前遇到的空白,next() 方法会自动将其去掉。只有输入有效字符后才将其后面输入的空白作为分隔符或者结束符。 | 以 Enter 为结束符,该返回的是输入回车之前的所有字符。 |
带空格字符串 | 🟥 | 🟩 |
如果要输入 int
或 float
类型的数据,在 Scanner
类中也有支持,但是在输入之前最好先使用 hasNextXxx()
方法进行验证,再使用 nextXxx()
来读取。
hasNextInt()
/nextInt()
:遇到空格时会停止读取,返回的结果为空格前读取到的部分。返回类型int
。hasNextDouble()
/nextDouble()
next()
和 nextLine()
连用时的注意事项next()
、nextInt()
读取数据后指针还在当前行,如果紧跟 nextLine()
,读取数据会出错。处理方法是:增多一个 nextLine()
「吃掉」换行符即可。具体案例详看下文案例「单组字符串输入输出」。
如果全程只使用 nextInt()
不会有上述问题。
形式 A:单组/多组 + EOF/零尾模式
输入结束模式:
- EOF 结束模式:输入有多组,文件末尾即输入结束。
- 零尾模式:输入有多组,输入参数均为 0 时即输入结束。
给定两个整数 a 和 b ,请你求出 a+b 的值。
1 | ************************* EOF模式 *************************** |
1 | import java.util.Scanner; |
形式 B:T 组
给定两个整数 a 和 b ,请你求出 a+b 的值。
首先会给出一个数字 T,然后给出 T 组数字。
1 | 输入: |
1 | public static void main(String[] args) { |
形式 C:单组字符串的输出与输出
这里将探讨 nextInt()
和 nextLine()
混用的问题。
给定一个长度为 n 的字符串 s ,请你将其倒置,然后输出。
1 | 输入: |
1 | public static void main(String[] args) { |
注意到,上面的参考答案都统一使用了 nextLine()
函数读取输入。那么我们能不能用 nextInt()
与 nextLine()
混合读取呢?答案是可以的,但是容易出错。
1 | public static void main(String[] args) { |
我们发现 str 并没有读取成功,这是因为第一次在读取 nextInt()
时,指针还在当前行,第二个 nextLine()
只读取到一个换行符。解决方法是在读取 nextInt()
后,在上面代码中「位置 A」处使用 nextLine()
「吃掉」第一行的换行符即可。
形式 D:字符串格式化
给定一个小数 n ,请你保留 3 位小数后输出。
如果原来的小数位数少于 3 ,需要补充 0 。
如果原来的小数位数多于 3 ,需要四舍五入到 3 位。
看到这题目时我还纳闷,以前在 LeetCode 刷题就好少这种返回指定精度数组并要求保留小数点后的 0 的,其实仔细想想以前刷题的核心代码模式要么返回 int
或 double
,不需要我们处理输出的位数或补充 0。而这 ACM 模式输出的是 String
,对输出自然会有另外的格式化要求。
1 | 输入: |
1 | public static void main(String[] args) { |
String.format
作为文本处理工具,为我们提供强大而丰富的字符串格式化功能。
对浮点数进行格式化:占位符格式为 %[index$][标识]*[最小宽度][.精度]转换符
。
可用标识 | 可用转换符 |
---|---|
- - ,在最小宽度内左对齐,不可以与 0 标识一起使用。- 0 ,若内容长度不足最小宽度,则在左边用 0 来填充。- # ,对 8 进制和 16 进制,8 进制前添加一个 0 ,16 进制前添加 0x 。- + ,结果总包含一个 + 或 - 号。- 空格 ,正数前加空格,负数前加 - 号。- , ,只用与十进制,每 3 位数字间用 , 分隔。- ( ,若结果为负数,则用括号括住,且不显示符号。 |
- b ,布尔类型,只要实参为非 false 的布尔类型,均格式化为字符串 true ,否则为字符串 false 。- n ,平台独立的换行符, 也可通过 System.getProperty(“line.separator”) 获取。- f ,浮点数型(十进制)。显示 9 位有效数字,且会进行四舍五入。如 99.99 。- a ,浮点数型(十六进制)。- e ,指数类型。如 9.38e+5 。- g ,浮点数型(比 %f ,%a 长度短些,显示 6 位有效数字,且会进行四舍五入) |
更多示例:
String.format("%09d",a)
:正整数不足 9 位的补充前导零。(🟩 单组_补充前导零_牛客题霸_牛客网 (nowcoder.com))