最近在學習在牛客網上面做一些算法練習題.
發現在一些情況下寫好的Java
代碼在本機運行時正常的結果,
但是就是無法通過牛客網的測試用例。
經過檢查,最終定位到讀取測試用例的位置上,發現:
Scanner scanner = new Scanner(System.in);
// 當使用 hasNextLine 方法實現判斷是否還有數據時
// 會報錯
while(scanner.hasNextLine()){
// TODO:implement code
}
// 當將 hasNextLine 修改爲 hasNext() 方法時
// 程序恢復正常
while(scanner.hasNext()){
// TODO:implement code
}
通過在網上搜索,獲取到這兩種方法的區別:
在檢查輸入流時:
hasNext()
方法會判斷接下來是否有非空字符.如果有,則返回true
,否則返回false
hasNextLine()
方法會根據行匹配模式去判斷接下來是否有一行(包括空行),如果有,則返回true
,否則返回false
比如當前我們有如下測試用例:
7 15 9 5
這個測試用例在牛客網上是以文件的形式進行存儲的.
而在 linux 系統中文件的結尾會有一個換行符\n
,也就是說從System.in
輸入流中真正讀取到的數據流是這樣的:
7 15 9 5\n
程序在處理完5之後,輸入流中就只剩下一個換行符\n
了,在處理完5之後while再去進行循環判斷,此時hasNext()
方法和hasNextLine()
方法去判斷得到的結果就產生了差異.
hasNext()
方法會認爲之後再沒有非空字符,會返回一個false
hasNextLine()
方法會認爲換行符\n
是一個空行,符合行的匹配模式,則會返回一個true
,但實際上由於之後再沒有數據了,所以會在讀取輸入流的時候發生異常,從而導致整個運行報錯.
建議方案:
採用hasNextXxxx()
的話,後面也要用nextXxxx()
:
- 比如前面用
hasNextLine()
,那麼後面要用nextLine()
來處理輸入; - 後面用
nextInt()
方法的話,那麼前面要使用hasNext()
方法去判斷.
參考資料:
oj的java輸入hasNext和hasNextLine區別
oi的java輸入hasNext和hasNextLine區別