Scanner 和 BufferedReader 的一些研究和思考
Scanner 和 BufferedReader 的一些研究和思考
Scanner 和 BufferedReader 的性能差距不必多说(详见文末)。不过在大部分题目中,IO 效率并不会成为瓶颈,关键还是算法本身。
尽管如此,我仍在尝试用 BufferedReader 平替 Scanner,下面是一些封装方案。
完整版
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
class FastIO {
private final BufferedReader br;
private StringTokenizer st;
FastIO() throws FileNotFoundException {
File f = new File("src/luogu/basic/input/input.txt");
InputStream in = f.exists() ? new FileInputStream(f) : System.in;
br = new BufferedReader(new InputStreamReader(in));
}
String next() throws IOException {
while (st == null || !st.hasMoreTokens()) {
String line = br.readLine();
if (line == null) return null;
st = new StringTokenizer(line);
}
return st.nextToken();
}
int nextInt() throws IOException {
return Integer.parseInt(next());
}
String nextLine() throws IOException {
return br.readLine();
}
long nextLong() throws IOException {
return Long.parseLong(next());
}
double nextDouble() throws IOException {
return Double.parseDouble(next());
}
}
精简版
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class FastIO {
BufferedReader br;
StringTokenizer st;
FastIO() {
File f = new File("");
InputStream in = f.exists() ? new FileInputStream(f) : System.in;
br = new BufferedReader(new InputStreamReader(in));
}
String next() {
while (st == null || !st.hasMoreTokens()) {
String line = br.readLine();
if (line == null) return null;
st = new StringTokenizer(line);
}
return st.nextToken();
}
int nextInt() {
return Integer.parseInt(next());
}
}
这个版本适合赛前快速编写,异常签名可以交给 IDE 自动补全。像 nextLine、nextLong 这些 API 在比赛中大概率用不到,可以先不写。
Scanner 配文件输入流
1
2
3
File f = new File("");//输入文件相对路径
InputStream in = f.exists() ? new FileInputStream(f) : System.in;
Scanner sc = new Scanner(in);
设计思路
为了保持代码最简洁,所以没有使用 try-catch。
关于输出优化:System.out.println 当然也可以用 BufferedWriter 优化,但在大部分情况下,使用 StringBuilder 在最后输出不会成为瓶颈,而且还多了一步 bw.flush(),所以不使用 BufferedWriter。
关于 hasNext 方法:实现起来代码较长,而且在题目中大概率会给出 N,或者可以按照下面的方式处理:
1
2
3
4
while (true) {
String s = io.next();
if (s == null) break;
}
File 构造函数填入输入文件的相对路径,这样可以直接读取文件作为输入,为调试节省时间。
该模板是为竞赛定制的,实际项目中还是需要多一些异常检查。
参考资料
本文由作者按照 CC BY 4.0 进行授权