輸入要考慮的基本問題
算法競賽題目一般會有多個測試用例,采用重定向的方式把數據送給程序。
然后觀察程序的輸出是否和預期的結果一致。
多數情況下,這些測試用例會以文件的形式存在。這就要注意以下的問題:
- 每一行的數據有多項,其分隔符不是完全確定,比如是:一個或多個空格。
- 每一行上的數據有多少項可能不知道。一直持續到本行結束。
- 一共有多少行可能不知道,一直到文件尾。
- 最后一行可能沒有回車換行符,直接遇到 EOF (文件結束標記)
- 在不同的操作系統下,換行的方式可能不同。
- 在提供字符串的時候,可能含有空格。
下面我們舉一些最常見的例子。
若干行,每行一個整數
測式數據
3
5
-7
9
import java.util.*;
import java.io.*;
public class A
{
public static void main(String[] args){
Scanner scan = new Scanner(System.in);
try{
while(true){
System.out.println("-> " + scan.nextInt());
}
}
catch(Exception e){}
}
}
使用這種方式,最后一行有沒有換行符都無關緊要。
甚至是最后有多個空行也不成問題。
若干行,每行兩個整數,用一個或多個空格分開
測試數據
10 20
30 40
50 60
import java.util.*;
import java.io.*;
public class B
{
public static void main(String[] args){
Scanner scan = new Scanner(System.in);
try{
while(true){
System.out.println("-> " + scan.nextInt() + "," + scan.nextInt());
}
}
catch(Exception e){}
}
}
先是讀入一個整數n,后面緊跟着n行字符串(可能含有空格)
測試數據
3
I am a student
test string
ok
import java.util.*;
public class C
{
public static void main(String[] args){
Scanner scan = new Scanner(System.in);
int n = scan.nextInt();
scan.nextLine(); //這個空讀十分關鍵
for(int i=0; i<n; i++){
System.out.println(scan.nextLine());
}
}
}
這里要注意的是:在讀入整數以后,不能直接按行讀入。而是要先空讀一行。
因為,nextInt 會越過空白,讀取整數,直到遇到了下一個空白(這里就是回車),
但它不會把遇到的這個分隔符吃掉,而是留在緩沖區中。
所以,此時如果直接按行讀入,就會先是空行,然后才能讀到需要的內容。
而 nextLine 就不同,它不會把回車符留在緩沖區,同時也不會把回車符返回在結果串中。
這樣安排有利於解決跨平台時,換行方式不一致的問題。
先是一個整數 n, 接下來有 n 行, 每行多個整數, 空格分開。要求對第每行求和
測試數據
4
1 2 3
10 20 30 40
333
444
此數據的最后一行沒有回車
方法一:
import java.util.*;
public class D
{
public static void main(String[] args){
Scanner scan = new Scanner(System.in);
int n = scan.nextInt();
scan.nextLine(); // 讀掉后面的一個回車符
for(int i=0; i<n; i++){
String s = scan.nextLine().trim();
String[] ss = s.split(" +"); // 因為1個或多個空格分開
int sum = 0;
for(int j=0; j<ss.length; j++){
sum += Integer.parseInt(ss[j]);
}
System.out.println(sum);
}
}
}
這是比較簡明的處理方法,每次把整個一行都讀進來,再進行分割。
但這樣處理可能有一個問題:當一行的數據太大(上百萬比如),可能導致讀入有問題。
如果能每次只讀入一個數據項,讀一個處理一個就很理想了。
所以才有方法二:
import java.util.*;
public class D2
{
public static void main(String[] args){
Scanner scan = new Scanner(System.in);
int n = scan.nextInt();
scan.nextLine(); // 讀掉后面的一個回車符
scan.useDelimiter(" +"); //默認的數據項分割符是空白和回車換行都可以,這里改為若干空格
for(int i=0; i<n; i++){
int sum = 0;
while(scan.hasNextInt()){
sum += scan.nextInt();
}
if(scan.hasNextLine()){ // 加 if 防止最后一行沒有回車符
sum += Integer.parseInt(scan.nextLine().trim());
}
System.out.println(sum);
}
}
}