欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 汽车 > 时评 > java竞赛优化输入输出效率

java竞赛优化输入输出效率

2025/9/14 18:02:40 来源:https://blog.csdn.net/px0405/article/details/145747629  浏览:    关键词:java竞赛优化输入输出效率

在编程竞赛中,输入输出效率至关重要。Java 的 `Scanner` 和 `System.out.println` 虽然简单,但在处理大规模数据时会严重拖慢速度。以下是 **竞赛专用输入输出模板** 及其原理详解,助你轻松应对高频 I/O 场景。

---### ⚡ 竞赛级输入输出模板(Java)
 

import java.io.*;
import java.util.*;public class Main {public static void main(String[] args) throws IOException {// 初始化输入输出BufferedReader br = new BufferedReader(new InputStreamReader(System.in));BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));StringTokenizer st;// 读取第一行数据(示例:N 和 Q)st = new StringTokenizer(br.readLine());int N = Integer.parseInt(st.nextToken());int Q = Integer.parseInt(st.nextToken());// 读取第二行数据(示例:N个整数)int[] arr = new int[N];st = new StringTokenizer(br.readLine());for (int i = 0; i < N; i++) {arr[i] = Integer.parseInt(st.nextToken());}// 处理 Q 次操作while (Q-- > 0) {st = new StringTokenizer(br.readLine());String op = st.nextToken();if (op.equals("1")) {int x = Integer.parseInt(st.nextToken());int y = Integer.parseInt(st.nextToken());// 处理操作1...} else {int x = Integer.parseInt(st.nextToken());// 处理操作2...bw.write(result + "\n"); // 使用 BufferedWriter 输出}}// 最终刷新输出bw.flush();}
}


```

---

### 🔥 为什么这样写更快?


1. **BufferedReader vs Scanner**:
   - `Scanner` 会进行复杂的正则解析和类型转换,效率极低。
   - `BufferedReader` 直接读取原始字节流,通过 `readLine()` 整行读取,减少 I/O 次数。

2. **StringTokenizer 分割字符串**:
   - 使用 `StringTokenizer` 分割字符串比 `split()` 更快,直接操作字符数组。
   - 通过 `nextToken()` 逐个获取分割后的字段,内存占用低。

3. **BufferedWriter 批量输出**:
   - `System.out.println` 每次调用都会触发 I/O,高频使用极慢。
   - `BufferedWriter` 会缓存输出内容,调用 `flush()` 时一次性写入,减少系统调用。

---

### 🛠 关键技巧与细节


#### 1. 异常处理简化
- 直接 `throws IOException` 避免 `try-catch`,竞赛代码允许这种写法。
- 生产代码不推荐,但竞赛中可极大简化代码。

#### 2. 高效读取不同类型数据
- **整数读取**:
  ```java
  int x = Integer.parseInt(st.nextToken());
  ```
- **长整型读取**:
  ```java
  long x = Long.parseLong(st.nextToken());
  ```
- **浮点数读取**:
  ```java
  double x = Double.parseDouble(st.nextToken());
  ```

#### 3. 处理多行输入
```java
// 读取 N 行数据
for (int i = 0; i < N; i++) {
    st = new StringTokenizer(br.readLine());
    // 处理每行数据...
}
```

#### 4. 输出优化
- 使用 `bw.write()` 代替 `System.out.println`。
- 注意手动添加换行符 `"\n"`。
- 最后必须调用 `bw.flush()` 确保输出全部内容。

---

### 🚀 性能对比
| 方法                   | 10^5次读取耗时 | 10^5次输出耗时 |
|-----------------------|---------------|---------------|
| `Scanner`             | ~1200ms       | ~800ms        |
| `System.out.println`  | -             | ~1500ms       |
| **本模板**            | **~200ms**    | **~100ms**    |

---

### 💡 常见问题解决


#### Q1: 为什么读取数据时要用 `st.nextToken()`?
- 因为 `StringTokenizer` 会按空格分割字符串,逐个返回字段,避免一次性生成数组。

#### Q2: 如何处理没有明确行数的输入?
- 使用循环读取直到 `br.readLine()` 返回 `null`:
  ```java
  String line;
  while ((line = br.readLine()) != null) {
      // 处理每行数据...
  }
  ```

#### Q3: 需要读取单个字符怎么办?
- 直接读取整行后取字符:
  ```java
  char c = br.readLine().charAt(0);
  ```

---

掌握这个模板后,你的 Java 竞赛代码 I/O 效率将大幅提升,轻松应对百万级数据量的题目!

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词