前言
本篇是在刷算法时,卡在超时题中解决的经验,一点见解微不足道,感谢您的阅览
问题场景
当无法从代码算法策略和数据结构层面优化代码时,或者其他语言(例如C,C++)用相同的方法却能解决问题,而Java却超时,问题可能出在Java的获取数据和最后处理输出数据上
数据输入层面
具体介绍
比如当题目有较大数据量的输入时,用Scanner或者BufferedReader明显力不从心,可以尝试一下StreamTokenizer, 它对与大量数据的输入获取效率明显高于Scanner和BufferedReader
Java.io.StreamTokenizer 类接受一个输入流并将其解析为"tokens",从而允许一次读取一个令牌。 流标记器可以识别标识符、数字、带引号的字符串和各种注释样式。 它对于大量数据的输入获取效率比BufferedReader还要高
代码中初始化如下
StreamTokenizer sc = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
常用方法
其中常用的方法如下
double nval
—— 如果当前标记是数字,则此字段包含该数字的值
int nextToken()
——该方法从该分词器的输入流中解析下一个分词。
用StreamTokenizer获取数据的两件套就是: nextToken() 和 (int)sc.nval
注意:这个nval千万别写错了,我之前写成navl,找半天没发现问题在哪,血泪教训
//声明StreamTokenizer
StreamTokenizer sc = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
//先获取下一个数
sc.nextToken();
//把获取的数字给转换为int型
int num = (int)sc.nval;
数据输出层面
具体介绍
相同的,对于控制台的大量输出,System.out.println也是比较乏力,效率比printwriter要低很多
先来说说我们常见的System.out.println,它是类 PrintStream 对象的一个引用,而控制台的输出由 print( ) 和 println() 这些方法都由类 PrintStream 定义
PrintStream是OutputStream的子类,PrintWriter是Writer的子类,两者处于对等的位置上.
但是,一个是字节打印流,一个是字符打印流
一个字符(char)是16bit,一个字节(byte)是8bit. PrintStream是写入一串8bit的数据。 PrintWriter是写入一串16bit的数据。
而且如果是对于字符打印的话,PrintWriter类更为合适
PrintStream打印的所有字符都将使用默认字符编码转换为字节。在需要编写字符而不是字节的情况下,应使用PrintWriter类。
常用方法
字符流PrintWriter类似于PrintStream,除了它以字符而不是字节编写。 PrintWriter还支持print(),println(),printf()和format()的所有方便的打印方式。它不会抛出IOException
PrintWriter out = new PrintWriter(System.out);
out.println();
out.flush();
out.close();