Java竞赛快速输入输出模板分享:让Scanner快十倍的无感升级方案
在算法竞赛或大规模数据处理场景中,Java的Scanner
类虽然使用方便,但其性能表现常常成为程序的瓶颈。尤其是在读取大量输入时,Scanner
的效率远低于基于缓冲的输入方式。今天,我想分享一个我在多次竞赛中打磨出的高效输入输出模板,它能让你在不改变编码习惯的前提下,大幅提升输入速度。
为什么需要这个模板?
在Codeforces、蓝桥杯等竞赛平台中,当输入数据量较大(如10^6级别以上)时,使用Scanner
很容易因为超时而失败。而BufferedReader
配合StringTokenizer
可以将输入速度提升数倍甚至十倍以上。
但直接使用BufferedReader
读取字符串再解析,代码变得繁琐。于是,我设计了一个封装类 MyScanner
,它兼容Scanner
,可以实现从Scanner
到高性能输入的无感切换。
我的竞赛模板代码
import java.io.*;
import java.util.*;
public class Main {
public static void main(String[] args) {
MyScanner sc = new MyScanner();
PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
//code here
out.flush(); // ⚠️ 关键!必须调用flush()
}
}
class MyScanner {
private BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
private StringTokenizer st;
public String nextLine() {
try {
return br.readLine();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
public String next() {
//注意这里要使用while
while (st == null || !st.hasMoreTokens()) {
st = new StringTokenizer(nextLine());
}
return st.nextToken();
}
public int nextInt() {
return Integer.parseInt(next());
}
public long nextLong() {
return Long.parseLong(next());
}
public double nextDouble() {
return Double.parseDouble(next());
}
}
模板的核心优势
✅ 1. 无感切换,零学习成本
你原来怎么用Scanner
,现在就怎么用MyScanner
:
// 原来
Scanner sc = new Scanner(System.in);
int a = sc.nextInt();
// 现在
MyScanner sc = new MyScanner();
int a = sc.nextInt(); // 用法完全一样!
无需修改任何业务逻辑代码,只需替换声明部分,即可享受性能飞跃。
✅ 2. 极致性能优化
使用
BufferedReader
进行整行读取,减少I/O调用次数。使用
StringTokenizer
高效分割字符串,比split()
更快。输出使用
PrintWriter
+BufferedWriter
组合,批量写入,减少系统调用。
在处理10万级别输入时,速度通常是Scanner
的5~10倍。
⚠️ 重要提醒:别忘了 out.flush()
使用缓冲输出时,数据并不会立即写入控制台或输出文件,而是先存入缓冲区。如果你忘记调用 out.flush()
,可能导致输出内容不完整甚至完全丢失!
务必在 main
函数的最后,在输出全部完成后调用:
out.flush();
使用建议
竞赛必备:每次打比赛前,先把这套模板复制到你的代码框架中。
命名规范:建议类名保持为
Main
,以兼容大多数OJ平台。扩展性:你可以根据需要为
MyScanner
添加nextChar()
、nextBoolean()
等方法。
总结
这个模板是我经过多次竞赛实战验证的“生产力工具”。它既保留了Scanner
的易用性,又拥有了BufferedReader
的高性能。无感升级 + 高效稳定 + 易于维护,非常适合算法竞赛、笔试、机试等对性能敏感的场景。
希望这个模板也能帮你避开“输入超时”的坑,写出更快、更稳的Java代码!
如果你有类似的优化技巧,欢迎在评论区分享交流!