OJ中使用Java语言的代码优化策略

本文介绍了在在线评测环境中使用Java编程时如何通过替换输入输出方式提高程序效率,避免超时。针对输入,推荐使用BufferedReader替代Scanner以减少读取时间;针对输出,则建议使用StringBuilder进行字符串拼接。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言:

因为Java语言的运行缓慢,因此在OJ中Java需要使用比C/C++更多的运行时间和运行内存,但是依然比较容易超时,因此在oj中几乎没有人使用Java来作为编程语言。

但是,如果你执着于使用Java语言,不妨记住以下的优化策略。

1. 替换输入

不要使用Scanner作为输入方式,使用BufferedReader作为替换,并在结束输入后尽早将其close()掉。

BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

//...

br.close();

之所以替换掉是因为Scanner输入运行及其缓慢,以下表格展示了输入的运行效率(表格来源:Faster Input for Java):

Table 1. Time to read 10,000,000 int values from file:

Input MethodTime (sec)
scanf(“%d”, &arg)3.78
Scanner.parseInt()29.52
BufferedReader + inline Integer.parseInt2.89
BufferedReader + Reader.nextInt method3.01

Table 2. Time to read 10,000,000 double values from file:

Input MethodTime (sec)
scanf(“%lf”, &arg)11.9
Scanner.parseDouble()66.86
BufferedReader + inline Double.parseDouble3.06
BufferedReader + Reader.nextDouble method3.14

同时,Faster Input for Java 利用StringTokenizer提供了封装好的输入类:

/** Class for buffered reading int and double values */
class Reader {
    static BufferedReader reader;
    static StringTokenizer tokenizer;

    /** call this method to initialize reader for InputStream */
    static void init(InputStream input) {
        reader = new BufferedReader(
                     new InputStreamReader(input) );
        tokenizer = new StringTokenizer("");
    }

    /** get next word */
    static String next() throws IOException {
        while ( ! tokenizer.hasMoreTokens() ) {
            //TODO add check for eof if necessary
            tokenizer = new StringTokenizer(
                   reader.readLine() );
        }
        return tokenizer.nextToken();
    }

    static int nextInt() throws IOException {
        return Integer.parseInt( next() );
    }

    static double nextDouble() throws IOException {
        return Double.parseDouble( next() );
    }
}

使用时如下即可:

  Reader.init( System.in ); // connect Reader to an input stream
  double x = Reader.nextDouble();
  int n = Reader.nextInt();

2. 替换输出

注:如果编译环境为JDK1.8,此条可忽略,因为JDK1.8中将”+”号的默认实现修改为了StringBuilder!

当你的输出是由多个变量拼接而成时,例如:

Sysyem.out.println("Student: " + name + ",age: " + age);

将其替换成StringBuilder,并使用append()方法拼接,即:

StringBuilder sb = new StringBuilder();
sb.append("Student: ").append(name).append(",age: ").append(age);
System.out.println(sb);

这是因为String对象为不可变对象,一旦被创建,就不能修改它的值。对于已经存在的String对象的修改都是重新创建一个新的对象,然后把新的值保存进去。

而StringBuilder不会创建新的对象,实际是指针的移动。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值