競技編程 (ACM/ICPC/藍橋杯等) 常見輸入格式:
第一行整數 n 表示後續數據組數或行數。
後續 n 行,每行包含**不定數量**的整數 (空格分隔)。
需將所有數據讀入二維數組或集合中處理。
3 <-- n = 3 行 1 2 3 <-- 第 1 行 3 個數 4 5 <-- 第 2 行 2 個數 6 7 8 9 <-- 第 3 行 4 個數
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 1. 讀取行數 n
int n = in.nextInt();
in.nextLine(); // 關鍵:消耗換行符,避免下一行 readLine 讀空
// 2. 定義二維數組/列表存儲不定長行數據
int[][] data = new int[n][];
// 3. 逐行讀取並解析
for (int i = 0; i < n; i++) {
String line = in.nextLine().trim();
if (line.isEmpty()) { // 處理空行
data[i] = new int[0];
continue;
}
String[] tokens = line.split("\\s+"); // 正則匹配多個空格/制表符
data[i] = new int[tokens.length];
for (int j = 0; j < tokens.length; j++) {
data[i][j] = Integer.parseInt(tokens[j]);
}
}
// 4. 業務邏輯處理 (示例:輸出每行數據)
for (int[] row : data) {
System.out.println(Arrays.toString(row));
}
in.close();
}
}
nextInt() 只讀取整數,留下換行符在緩衝區,必須調用一次 nextLine() 清空,否則第一行數據會被讀為空字符串。split(" ") 遇到連續空格會產生空字符串元素,導致解析錯誤。`\\s+` 匹配任意長度空白字符。BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(br.readLine());
int[][] data = new int[n][];
for (int i = 0; i < n; i++) {
StringTokenizer st = new StringTokenizer(br.readLine());
data[i] = new int[st.countTokens()];
for (int j = 0; j < data[i].length; j++) {
data[i][j] = Integer.parseInt(st.nextToken());
}
}
| 輸入格式 | 處理策略 |
|---|---|
| 第一行 n,後續 n 行,每行第一個數 m 表示本行後續有 m 個數 | 先讀 m,再循環讀 m 個數 |
| 未知行數,以 EOF 或特定標記 (如 0) 結束 | while ((line = br.readLine()) != null) { if (line.equals("0")) break; ... } |
| 單行包含所有數據,先給總數 | 一次性 readLine().split() 全部解析 |
掌握 Scanner/BufferedReader 配合 split/Tokenizer 的動態二維數組解析模板,是 Java 競技編程處理複雜輸入格式的核心基本功。實戰中根據數據規模選擇高性能 IO 方案。