快读快写模板

Smile_slime_47

概述


Java的Scanner类是基于正则表达式匹配的,所以读写效率是极低的,本质上是基于Scanner类对于不同输入数据类型的匹配的问题。其地位约等于C++中的cin

而在竞赛中考虑到输入输出的数据类型都是固定的,我们可以通过一些其他的IO库来实现更高效率的读写方式

StringTokenizer类


StringTokenizer可以将输入的字符串按照指定的分割符将其切分为多个子字符串,将每个子字符串称为token

构造方法

1
2
3
4
5
6
7
8
//解析输入的字符串,以\t \n \r \f为分隔符
public StringTokenizer(String str)

//解析输入的字符串,以delim为分隔符
public StringTokenizer(String str, String delim)

//解析输入的字符串,以delim为分隔符,当returnDelims为true时解析的子字符串包含分隔符
public StringTokenizer(String str, String delim, boolean returnDelims)

成员方法

1
2
3
4
5
//获取下一个token子字符串
public String nextToken()

//返回是否存在下一个token
public boolean hasMoreTokens()

自行实现数据类型的解析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class ExtendedStringTokenizer extends StringTokenizer {
public ExtendedStringTokenizer(String str) {
super(str);
}
public long nextLong() {
return Long.parseLong(this.nextToken());
}
public double nextDouble() {
return Double.parseDouble(this.nextToken());
}
public int nextInt() {
return Integer.parseInt(nextToken());
}
}

InputStream和Reader


  • 我们可以通过new InputStreamReader(System.in)和BufferedReader来解析一个System.in的InputStream
  • 也可以通过new DataInputStream(System.in)和StringTokenizer来解析

一次性读入

1
2
DataInputStream stream = new DataInputStream(inputStream);
ExtendedStringTokenizer tokenizer = new ExtendedStringTokenizer(new String(stream.readAllBytes()));

逐行读入

逐行读入的效率是低于一次性读入的

不过对于reader而言,提供了更多解析的方式

1
2
3
4
5
6
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
String line;
while ((line = reader.readLine()) != null) {
ExtendedStringTokenizer tokenizer = new ExtendedStringTokenizer(line);
// TODO: your code
}

除了readLine以外,reader还支持其他的读入方式

1
2
3
4
5
6
7
8
//读入一个字符
public int read()

//读入一行字符串
public String readLine()

//从reader中读取len长度的字符串,从cbuf[off]开始装入cbuf中
public int read(char cbuf[], int off, int len)
Comments