Java自带的Scanner在面对大批量数据的时候会显得特别慢,特别是我们在写算法题题时,如果使用Scanner来输入,那么当测试用例数据量达到几千几万的时候,我们的程序光花在读数据的时间就需要几百ms,这对我们来说是不能接受的,明明算法是对的,却因为java自身的原因,导致超时。
其实对于输入来说,是有办法提高速度的。
下面我给出了我写好的一个输入输出封装类:
package io;
import java.io.*;
public class QuickIO
{
public static QuickInput in=new QuickInput();
public static PrintWriter out=new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
}
class QuickInput
{
private BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
private StreamTokenizer tokenizer = new StreamTokenizer(br);
public Integer nextInt()
{
try {
tokenizer.nextToken();
if(tokenizer.ttype == StreamTokenizer.TT_EOF)
{
return null;
}
if(tokenizer.ttype == StreamTokenizer.TT_NUMBER)
{
return (int)tokenizer.nval;
}
if(tokenizer.ttype == StreamTokenizer.TT_WORD)
{
return Integer.valueOf(tokenizer.sval);
}
}catch (IOException e)
{
e.printStackTrace();
}
return null;
}
public String nextWord()
{
try {
tokenizer.nextToken();
if(tokenizer.ttype == StreamTokenizer.TT_EOF)
{
return null;
}
if(tokenizer.ttype == StreamTokenizer.TT_NUMBER)
{
return String.valueOf(tokenizer.nval);
}
if(tokenizer.ttype == StreamTokenizer.TT_WORD)
{
return tokenizer.sval;
}
}catch (IOException e)
{
e.printStackTrace();
}
return null;
}
public String readLine()
{
try {
return br.readLine();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
基本思路就是,整行读的时候用BufferedReader,读String和int等就用StreamTokenizer。
但是这种封装其实局限性非常大。
这个nextInt还好,这个nextWord(注意我没用nextString来命名,是因为它确实做不到常规nextString的功能)只能读取一段连续的数字或者连续的字母。比如我输入的是hi789,那么只能读到hi,输入76ee只能读到76,输入lp:l只能读取到lp(因为:是非字母)。总之它只能处理字母和数字。
所以实际应用的时候我们需要根据实际情况灵活变通来使用。
下面给出测试代码:
public class Main
{
public static void main(String[] args) {
int n=QuickIO.in.nextInt();
String s=QuickIO.in.nextWord();
String line=QuickIO.in.readLine();
System.out.println(n);
System.out.println(s);
System.out.println(line);
}
}
输入:
75
hello
hi upc
输出:
75
hello
hi upc