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

輸入要考慮的基本問題

算法競賽題目通常會有多個測試用例,採用重定向的方式把數據送給程序。
而後觀察程序的輸出是否和預期的結果一致。
多數狀況下,這些測試用例會以文件的形式存在。這就要注意如下的問題: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){}
    }
}

使用這種方式,最後一行有沒有換行符都可有可無。
甚至是最後有多個空行也不成問題。操作系統

若干行,每行兩個整數,用一個或多個空格分開

測試數據code

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 就不一樣,它不會把回車符留在緩衝區,同時也不會把回車符返回在結果串中。
這樣安排有利於解決跨平臺時,換行方式不一致的問題。string

先是一個整數 n, 接下來有 n 行, 每行多個整數, 空格分開。要求對第每行求和

測試數據it

4
1 2 3
10 20 30 40
333
444

此數據的最後一行沒有回車
方法一:io

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

這是比較簡明的處理方法,每次把整個一行都讀進來,再進行分割。
但這樣處理可能有一個問題:當一行的數據太大(上百萬好比),可能致使讀入有問題。
若是能每次只讀入一個數據項,讀一個處理一個就很理想了。
因此纔有方法二:class

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);
        }
    }
}
相關文章
相關標籤/搜索