如何從標准輸入讀入數據(1) -- java語言


輸入要考慮的基本問題

算法競賽題目一般會有多個測試用例,采用重定向的方式把數據送給程序。
然后觀察程序的輸出是否和預期的結果一致。
多數情況下,這些測試用例會以文件的形式存在。這就要注意以下的問題:

  1. 每一行的數據有多項,其分隔符不是完全確定,比如是:一個或多個空格。
  2. 每一行上的數據有多少項可能不知道。一直持續到本行結束。
  3. 一共有多少行可能不知道,一直到文件尾。
  4. 最后一行可能沒有回車換行符,直接遇到 EOF (文件結束標記)
  5. 在不同的操作系統下,換行的方式可能不同。
  6. 在提供字符串的時候,可能含有空格。

下面我們舉一些最常見的例子。

若干行,每行一個整數

測式數據

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);
		}
	}
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM