Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/370.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
什么';在Java中读取System.in的最快方法是什么?_Java_Optimization_Inputstream_Stdin - Fatal编程技术网

什么';在Java中读取System.in的最快方法是什么?

什么';在Java中读取System.in的最快方法是什么?,java,optimization,inputstream,stdin,Java,Optimization,Inputstream,Stdin,我正在使用Scanner(System.in)从标准中读取由空格或换行符分隔的一组整数 在Java中有没有更快的方法 在Java中有没有更快的方法 对。扫描仪相当慢(至少根据我的经验) 如果您不需要验证输入,我建议您将流包装在BufferedInputStream中,并使用类似String.split/Integer.parseInt的内容 一个小小的比较: 使用此代码读取17兆字节(4233600个数字) Scanner scanner = new Scanner(System.in); w

我正在使用
Scanner(System.in)
从标准中读取由空格或换行符分隔的一组整数

在Java中有没有更快的方法

在Java中有没有更快的方法

对。扫描仪相当慢(至少根据我的经验)

如果您不需要验证输入,我建议您将流包装在BufferedInputStream中,并使用类似
String.split
/
Integer.parseInt
的内容


一个小小的比较:

使用此代码读取17兆字节(4233600个数字)

Scanner scanner = new Scanner(System.in);
while (scanner.hasNext())
    sum += scanner.nextInt();
在我的机器上运行了3.3秒。而这个片段

BufferedReader bi = new BufferedReader(new InputStreamReader(System.in));
String line;
while ((line = bi.readLine()) != null)
    for (String numStr: line.split("\\s"))
        sum += Integer.parseInt(numStr);
用了0.7秒


通过进一步弄乱代码(使用
String.indexOf
/
String.substring
)在
上迭代),您可以很容易地将代码缩短到大约0.1秒,但我想我已经回答了你的问题,我不想把它变成某种代码高尔夫。

你可以从
系统中以一位数一位数的方式阅读。看看这个答案:

我在这里复制代码(几乎没有修改)。基本上,它读取整数,由任何非数字分隔。(归功于原作者。)

private static int readInt()引发IOException{
int-ret=0;
布尔值=假;
对于(int c=0;(c=System.in.read())!=-1;){
如果(c>='0'&&c我创建了一个小类,它的工作原理与Java的Scanner类似,但速度比它快很多,事实上,它也比BufferedReader快。下面是一个条形图,显示了我创建的InputReader类的性能,该类从标准输入读取不同类型的数据:

在使用InputReader类时,有两种不同的方法可以查找来自System.com的所有数字之和:

int sum = 0;
InputReader in = new InputReader(System.in);

// Approach #1
try {

    // Read all strings and then parse them to integers (this is much slower than the next method).
    String strNum = null;
    while( (strNum = in.nextString()) != null )
        sum += Integer.parseInt(strNum);

} catch (IOException e) { }

// Approach #2
try {

    // Read all the integers in the stream and stop once an IOException is thrown
    while( true ) sum += in.nextInt();

} catch (IOException e) { }

从编程的角度来看,这个定制的扫描和打印类比Java内置的Scanner和BufferedReader类要好得多

import java.io.InputStream;
import java.util.InputMismatchException;
import java.io.IOException;

public class Scan
{

private byte[] buf = new byte[1024];

private int total;
private int index;
private InputStream in;

public Scan()
{
    in = System.in;
}

public int scan() throws IOException
{

    if(total < 0)
        throw new InputMismatchException();

    if(index >= total)
    {
        index = 0;
        total = in.read(buf);
        if(total <= 0)
            return -1;
    }

    return buf[index++];
}


public int scanInt() throws IOException
{

    int integer = 0;

    int n = scan();

    while(isWhiteSpace(n))   /*  remove starting white spaces   */
        n = scan();

    int neg = 1;
    if(n == '-')
    {
        neg = -1;
        n = scan();
    }

    while(!isWhiteSpace(n))
    {

        if(n >= '0' && n <= '9')
        {
            integer *= 10;
            integer += n-'0';
            n = scan();
        }
        else
            throw new InputMismatchException();
    }

    return neg*integer;
}


public String scanString()throws IOException
{
    StringBuilder sb = new StringBuilder();

    int n = scan();

    while(isWhiteSpace(n))
        n = scan();

    while(!isWhiteSpace(n))
    {
        sb.append((char)n);
        n = scan();
    }

    return sb.toString();
}


public double scanDouble()throws IOException
{
    double doub=0;
    int n=scan();
    while(isWhiteSpace(n))
    n=scan();
    int neg=1;
    if(n=='-')
    {
        neg=-1;
        n=scan();
    }
    while(!isWhiteSpace(n)&& n != '.')
    {
        if(n>='0'&&n<='9')
        {
            doub*=10;
            doub+=n-'0';
            n=scan();
        }
        else throw new InputMismatchException();
    }
    if(n=='.')
    {
        n=scan();
        double temp=1;
        while(!isWhiteSpace(n))
        {
            if(n>='0'&&n<='9')
            {
                temp/=10;
                doub+=(n-'0')*temp;
                n=scan();
            }
            else throw new InputMismatchException();
        }
    }
    return doub*neg;
}

public boolean isWhiteSpace(int n)
{
    if(n == ' ' || n == '\n' || n == '\r' || n == '\t' || n == -1)
        return true;

    return false;
}

public void close()throws IOException
{
    in.close();
}
}
您可以使用BufferedReader读取数据

BufferedReader inp=新的BufferedReader(新的InputStreamReader(System.in));
int t=Integer.parseInt(inp.readLine());
而(t-->0){
int n=Integer.parseInt(inp.readLine());
int[]arr=新的int[n];
字符串行=inp.readLine();
字符串[]str=line.trim().split(\\s+);

对于(int i=0;i如果您从竞争性编程的角度询问,如果提交速度不够快,那么将是TLE。
然后可以检查以下方法以从System.in检索字符串。 我从java最好的程序员之一(竞争网站)那里学到了


StringTokenizer
是一种读取由标记分隔的字符串输入的更快方法

检查以下示例以读取由空格分隔的整数字符串并存储在arraylist中

String str = input.readLine(); //read string of integers using BufferedReader e.g. "1 2 3 4"
List<Integer> list = new ArrayList<>();
StringTokenizer st = new StringTokenizer(str, " ");
while (st.hasMoreTokens()) {
    list.add(Integer.parseInt(st.nextToken()));
} 
String str=input.readLine();//使用BufferedReader读取整数字符串,例如“1 2 3 4”
列表=新的ArrayList();
StringTokenizer st=新的StringTokenizer(str,“”);
而(st.hasMoreTokens()){
add(Integer.parseInt(st.nextToken());
} 

这是完整版本的快速读写器。我还使用了缓冲

import java.io.*;
import java.util.*;


public class FastReader {
    private static StringTokenizer st;
    private static BufferedReader in;
    private static PrintWriter pw;


    public static void main(String[] args) throws IOException {

        in = new BufferedReader(new InputStreamReader(System.in));
        pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
        st = new StringTokenizer("");

        pw.close();
    }

    private static int nextInt() throws IOException {
        return Integer.parseInt(next());
    }
    private static long nextLong() throws IOException {
        return Long.parseLong(next());
    }
    private static double nextDouble() throws IOException {
        return Double.parseDouble(next());
    }
    private static String next() throws IOException {
        while(!st.hasMoreElements() || st == null){
            st = new StringTokenizer(in.readLine());
        }
        return st.nextToken();
    }
}

一次又一次地从磁盘读取会使扫描仪速度变慢。我喜欢使用BufferedReader和Scanner的组合,以充分利用这两个方面。即BufferedReader的速度和扫描仪丰富而简单的API

Scanner scanner = new Scanner(new BufferedReader(new InputStreamReader(System.in)));

你每秒需要读入多少百万个整数?如果你的整数少于几百万,我不会太担心。我在编程竞赛中遇到了这个问题。你会遇到数千个问题实例,每个问题实例都有数千个数字,这并不奇怪(以获得一些信心,确保您不会侥幸获得一个复杂度不高的解决方案)是的,这是我在几千条线上阅读的编程竞赛,我注意到C++中的CIN比爪哇的扫描器快得多,并且对另一种选择的存在感到怀疑。未来的搜索者也应该看看这个线程:但是,你最好有一个很好的理由来增加你的代码中的杂乱。与StringTokenizer一样快。要获得最有效的代码,请使用StringTokenizer。OpenJKD8的readLine()
速度不明显快于
BufferedReader.readLine()
。缓冲区大小为2048,流长度为2.5 MB。但更糟糕的是:代码中断(UTF-8)字符编码。
    StringBuffer sb = new StringBuffer();
    for(int i=0;i<n;i++){
              sb.append(arr[i]+" "); 
            }
    System.out.println(sb);
private String ns()
{
    int b = skip();
    StringBuilder sb = new StringBuilder();
    while(!(isSpaceChar(b))){ // when nextLine, (isSpaceChar(b) && b != ' ')
        sb.appendCodePoint(b);
        b = readByte();
    }
    return sb.toString();
}`
String str = input.readLine(); //read string of integers using BufferedReader e.g. "1 2 3 4"
List<Integer> list = new ArrayList<>();
StringTokenizer st = new StringTokenizer(str, " ");
while (st.hasMoreTokens()) {
    list.add(Integer.parseInt(st.nextToken()));
} 
import java.io.*;
import java.util.*;


public class FastReader {
    private static StringTokenizer st;
    private static BufferedReader in;
    private static PrintWriter pw;


    public static void main(String[] args) throws IOException {

        in = new BufferedReader(new InputStreamReader(System.in));
        pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
        st = new StringTokenizer("");

        pw.close();
    }

    private static int nextInt() throws IOException {
        return Integer.parseInt(next());
    }
    private static long nextLong() throws IOException {
        return Long.parseLong(next());
    }
    private static double nextDouble() throws IOException {
        return Double.parseDouble(next());
    }
    private static String next() throws IOException {
        while(!st.hasMoreElements() || st == null){
            st = new StringTokenizer(in.readLine());
        }
        return st.nextToken();
    }
}
Scanner scanner = new Scanner(new BufferedReader(new InputStreamReader(System.in)));