相信我们已经非常熟悉 LeetCode 那种「站内文章核心代码」的写题模式,在这种模式下,我们可以更专注于代码逻辑本身。然而一些公司或学校的机考仍然使用 ACM 文件输入输出模式,在这种模式下需要对题目输入输出的逻辑进行额外的处理。

最最基本的输出写法。

1
System.out.println("Hello Nowcoder!"); // 换行输出 IDEA 下快捷输入:sout

java.util.Scanner 是 Java5 的新特征,我们可以通过 Scanner 类来获取用户的输入。

1
2
// 创建 Scanner 对象的基本语法
Scanner in = new Scanner(System.in);

输入时用到类 Scanner 类,里面有几个常用方法:

  • hasNext():用于判断是否还有输入的数据,常放在 while 循环中判断输入是否结束。
  • next():读到空格就停止读取。适合读取单个字符或字符串。返回类型 String
  • nextLine():读取一整行数据,碰到换行则停止。返回类型 String

next()nextLine() 区别:

函数 next() nextLine()
是否阻塞 一定要读取到有效字符后才可以结束输入
结束符 对输入有效字符之前遇到的空白,next() 方法会自动将其去掉。只有输入有效字符后才将其后面输入的空白作为分隔符或者结束符。 以 Enter 为结束符,该返回的是输入回车之前的所有字符。
带空格字符串 🟥 🟩

如果要输入 intfloat 类型的数据,在 Scanner 类中也有支持,但是在输入之前最好先使用 hasNextXxx() 方法进行验证,再使用 nextXxx() 来读取。

  • hasNextInt() / nextInt():遇到空格时会停止读取,返回的结果为空格前读取到的部分。返回类型 int
  • hasNextDouble() / nextDouble()
next()nextLine() 连用时的注意事项

next()nextInt() 读取数据后指针还在当前行,如果紧跟 nextLine(),读取数据会出错。处理方法是:增多一个 nextLine()「吃掉」换行符即可。具体案例详看下文案例「单组字符串输入输出」。

如果全程只使用 nextInt() 不会有上述问题。

形式 A:单组/多组 + EOF/零尾模式

输入结束模式:

  • EOF 结束模式:输入有多组,文件末尾即输入结束。
  • 零尾模式:输入有多组,输入参数均为 0 时即输入结束。

给定两个整数 a 和 b ,请你求出 a+b 的值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
************************* EOF模式 ***************************
输入:
1 2
114 514
2024 727

输出:
3
628
2751

************************* 零尾模式 ***************************
输入:
1 2
114 514
2024 727
0 0

输出:
3
628
2751
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import java.util.Scanner;

public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNextInt()) { // 注意 while 处理多个 case
int a = in.nextInt();
int b = in.nextInt();

/*
零尾模式只需在此处增加以下语句即可
if(a==0 && b==0)break;
*/

System.out.println(a + b);
}
}
}

形式 B:T 组

给定两个整数 a 和 b ,请你求出 a+b 的值。

首先会给出一个数字 T,然后给出 T 组数字。

1
2
3
4
5
6
7
8
9
10
输入:
3
1 2
114 514
2024 727

输出:
3
628
2751
1
2
3
4
5
6
7
8
9
10
11
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
int T = in.nextInt();

while (T--!=0) { // 注意 while 处理多个 case
int a = in.nextInt();
int b = in.nextInt();
System.out.println(a + b);
}
}

形式 C:单组字符串的输出与输出

这里将探讨 nextInt()nextLine() 混用的问题。

给定一个长度为 n 的字符串 s ,请你将其倒置,然后输出。

1
2
3
4
5
6
输入:
5
abcde

输出:
edcba
1
2
3
4
5
6
7
8
9
10
11
12
13
public static void main(String[] args) {
Scanner in = new Scanner(System.in);

int len = Integer.valueOf(in.nextLine());
String str = in.nextLine();

char[] res = new char[len];
for(int i=0;i<len;i++){
res[len-1-i]=str.charAt(i);
}

System.out.println(new String(res));
}

注意到,上面的参考答案都统一使用了 nextLine() 函数读取输入。那么我们能不能用 nextInt()nextLine() 混合读取呢?答案是可以的,但是容易出错。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public static void main(String[] args) {
Scanner in = new Scanner(System.in);

int len = in.nextInt();
/** 位置 A **/
String str = in.nextLine();

System.out.println("读取到的len:"+len);
System.out.println("读取到的str:"+str);
}
/*
输出:
读取到的len:5
读取到的str:
*/

我们发现 str 并没有读取成功,这是因为第一次在读取 nextInt() 时,指针还在当前行,第二个 nextLine() 只读取到一个换行符。解决方法是在读取 nextInt() 后,在上面代码中「位置 A」处使用 nextLine()「吃掉」第一行的换行符即可。

形式 D:字符串格式化

给定一个小数 n ,请你保留 3 位小数后输出。
如果原来的小数位数少于 3 ,需要补充 0 。
如果原来的小数位数多于 3 ,需要四舍五入到 3 位。

看到这题目时我还纳闷,以前在 LeetCode 刷题就好少这种返回指定精度数组并要求保留小数点后的 0 的,其实仔细想想以前刷题的核心代码模式要么返回 intdouble,不需要我们处理输出的位数或补充 0。而这 ACM 模式输出的是 String,对输出自然会有另外的格式化要求。

1
2
3
4
5
输入:
1.23

输出:
1.230
1
2
3
4
5
6
7
8
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNextDouble()) { // 注意 while 处理多个 case
double a = in.nextDouble();
System.out.println(String.format("%.3f", a).toString());
}
}

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 位有效数字,且会进行四舍五入)

更多示例: