在Java中的单行上使用BufferedReader而不是Scanner Class来实现多个整数是否最佳?

时间:2017-09-18 14:15:16

标签: java time-complexity java.util.scanner bufferedreader

由于在从用户输入值时缓冲读取器比扫描器类快得多,但是在大多数算法竞赛中观察到或者在采访的情况下,在单个输入线上通常存在多个整数。因此,使用扫描仪类变得更容易 -

    Scanner in=new Scanner(System.in);
    int a=in.nextInt();
    int b=in.nextInt();

对于Buffered Reader,您必须先输入一行(因为没有readInt选项),然后根据行上的整数解析该行 -

    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    int a,b;
    String line = br.readLine(); 
    String[] strs = line.trim().split("\\s+");
    a=Integer.parseInt(strs[0]);
    b=Integer.parseInt(strs[1]);

虽然在后一种情况下输入可能更快,但是解析不会花费很多时间将获得的字符串划分为单独的整数? 因此,在上述哪一种更优或更快的情况下?

谢谢。

2 个答案:

答案 0 :(得分:4)

非常错误的方法:您正在谈论用户输入如何处理人类时间尺度上提供的内容绝对没有关系。

人类操作"秒",在某些情况下"毫秒"。

而扫描仪和BufferedReader之间在性能方面的增量可能在秒范围内,甚至可能纳米

即使我们没有谈论在控制台上输入内容的人(但使用管道,如cat somefile | java Whatever) - 你仍然有 IO 大规模发生。您的应用程序将花费99.99%的时间等待IO发生。最后如何处理传入的字符串并不重要。

换句话说:您最好将时间花在编写干净代码上,这样可以直接向其人类读者轻松理解。然后让JIT发挥其魔力。

因为问题是关于处理"基于文件"输入 - 自己去个人资料。我会在这做什么:

  • 创建一个抽象层,允许我轻松在不同的实现之间切换
  • 然后我会开始基准不同的解决方案(仔细阅读this以准备此类活动)

你看,最后两个代码片段都会做很多类似的事情。扫描程序仍然在处理某些事情,您需要深入研究相应的源代码一段时间才能理解扫描程序解析和BufferedReader读取+手动解析之间的潜在差异。

答案 1 :(得分:3)

这是代码清晰度比速度更重要的情况之一。

很容易看出使用Scanner的代码会发生变化,并且非常自然地读取。

另一方面,使用BufferedReader的代码在执行需要执行的操作之前执行一些额外的任务(从输入中读取两个整数),因此代码的读者可能会花几秒钟来查看正在继续。

当然,两个实现都缺少一些错误处理代码。例如,第二个实现需要检查split是否正好返回了两个项目。如果第一个实现省略了所有错误检查,则调用者将收到一条消息,指出输入中没有整数。第二个实现将使索引超出范围异常,这将需要额外的研究来查看正在发生的事情。

就解析而言,它必须在两种情况下发生,因此您最终会花费大约相同数量的CPU周期来处理它。