Java蓝桥杯输入输出方法总结
在蓝桥杯竞赛中,合适的输入输出方法对提高程序运行效率至关重要。本文将系统地介绍Java中各种输入输出方法,并提供性能对比分析。
1. Scanner类
1.1 基本用法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| import java.util.Scanner;
public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); String str = sc.next(); String line = sc.nextLine(); double d = sc.nextDouble(); sc.close(); } }
|
1.2 优缺点
- 优点:使用简单,功能齐全
- 缺点:性能较差,不适合大量数据的输入
2. BufferedReader类
2.1 基本用法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.IOException;
public class Main { public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String line = br.readLine(); int n = Integer.parseInt(br.readLine()); String[] nums = br.readLine().split(" "); int[] arr = new int[nums.length]; for (int i = 0; i < nums.length; i++) { arr[i] = Integer.parseInt(nums[i]); } br.close(); } }
|
2.2 优缺点
- 优点:效率高,适合处理大量数据
- 缺点:使用相对复杂,需要处理IOException
3. StreamTokenizer类
3.1 基本用法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.StreamTokenizer; import java.io.IOException;
public class Main { public static void main(String[] args) throws IOException { StreamTokenizer st = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in))); st.nextToken(); int n = (int) st.nval; st.nextToken(); String str = st.sval; } }
|
3.2 优缺点
- 优点:自动分词,处理数字和字符串方便
- 缺点:使用较为复杂
4. 快读快写模板
4.1 基于BufferedReader的快读模板
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
| import java.io.*;
class FastReader { private BufferedReader br; private StringTokenizer st; public FastReader() { br = new BufferedReader(new InputStreamReader(System.in)); } public String next() { while (st == null || !st.hasMoreElements()) { try { st = new StringTokenizer(br.readLine()); } catch (IOException e) { e.printStackTrace(); } } return st.nextToken(); } public int nextInt() { return Integer.parseInt(next()); } public long nextLong() { return Long.parseLong(next()); } public double nextDouble() { return Double.parseDouble(next()); } public String nextLine() { String str = ""; try { str = br.readLine(); } catch (IOException e) { e.printStackTrace(); } return str; } }
public class Main { public static void main(String[] args) { FastReader fr = new FastReader(); int n = fr.nextInt(); long m = fr.nextLong(); double d = fr.nextDouble(); String s = fr.next(); String line = fr.nextLine(); } }
|
4.2 基于字节流的极速读写模板
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
| import java.io.*;
class UltraIO { private static final int BUFFER_SIZE = 1 << 16; private final DataInputStream din; private final DataOutputStream dout; private final byte[] buffer; private int bufferPointer, bytesRead; public UltraIO() { din = new DataInputStream(System.in); dout = new DataOutputStream(System.out); buffer = new byte[BUFFER_SIZE]; bufferPointer = bytesRead = 0; } public String readLine() throws IOException { byte[] buf = new byte[64]; int cnt = 0, c; while ((c = read()) != -1) { if (c == '\n') break; buf[cnt++] = (byte) c; } return new String(buf, 0, cnt); } public int nextInt() throws IOException { int ret = 0; byte c = read(); while (c <= ' ') c = read(); boolean neg = (c == '-'); if (neg) c = read(); do { ret = ret * 10 + c - '0'; } while ((c = read()) >= '0' && c <= '9'); if (neg) return -ret; return ret; } private void fillBuffer() throws IOException { bytesRead = din.read(buffer, bufferPointer = 0, BUFFER_SIZE); if (bytesRead == -1) buffer[0] = -1; } private byte read() throws IOException { if (bufferPointer == bytesRead) fillBuffer(); return buffer[bufferPointer++]; } public void close() throws IOException { if (din == null) return; din.close(); } }
public class Main { public static void main(String[] args) throws IOException { UltraIO io = new UltraIO(); int n = io.nextInt(); String line = io.readLine(); io.close(); } }
|
5. 性能对比
以下是各种输入方法读取100万个整数的性能对比:
- Scanner:约2000ms
- BufferedReader:约500ms
- StreamTokenizer:约400ms
- FastReader:约300ms
- UltraIO:约150ms
6. 使用建议
- 对于简单题目或数据量较小的情况,使用Scanner即可
- 对于数据量中等的题目,使用BufferedReader或FastReader
- 对于数据量极大或对时间要求极高的题目,使用UltraIO模板
- 在实际比赛中,建议将快读模板代码准备好,以备不时之需
7. 注意事项
- 使用Scanner时注意nextInt()和nextLine()混用可能导致的问题
- BufferedReader必须处理IOException
- 在使用完输入流后记得关闭(close)
- 对于竞赛中的多组输入,注意处理输入结束的条件
总结
在蓝桥杯竞赛中,选择合适的输入输出方法可以显著提高程序的运行效率。对于不同的题目要求,应当灵活选择合适的输入方法。建议平时多加练习各种输入方法的使用,以便在比赛中得心应手。